This project aims to reverse engineer the Upright GO V.1 posture corrector device for learning and to enable the creation of an open-source alternative to the official (discontinued) mobile application.
Status: Protocol fully mapped β
2026-07 update: the BLE protocol is now 100% characterized β every characteristic the device exposes is decoded or explicitly catalogued, with expected behaviors verified on real hardware. See PROTOCOL.md for the complete reference (calibration lifecycle, posture status machine, worn sensor, pause mode, battery, per-minute telemetry, and corrections to this README's original work-in-progress table). The findings were produced while building Open Posture Companion, an open-source replacement for the discontinued official app.
Historical note: the project was on hold for a while due to apparently a firmware corruption on the device I was using. It seems that the device allows firmware updates without checking the integrity of the firmware, which can lead to a bricked device - and I believe that's what happened to mine while I was too excited to test all write characteristics by pushing \x1. π All later exploration used a strict read-first methodology (described in PROTOCOL.md) β learn from my mistake and never write to the aae0 service.
- Introduction
- Full Protocol Reference (PROTOCOL.md)
- Hardware
- Teardown
- TODO
- Credits
- Disclaimer
- Acknowledgements
The Upright GO is a posture corrector device that is worn on the upper back. It is designed to help users improve their posture by vibrating when the user slouches. The device is connected to a mobile application that provides feedback on the user's posture. The Upright GO V.1 is the first version of the device, and it has been discontinued in favor of the Upright GO V.2.
Ever since the Upright GO V.1 was discontinued, the mobile application has stopped working. While the device is still usable without the app, there's no workaround to provide users with historical data and feedback on their posture. This project aims to reverse engineer the Upright GO V.1 to
- Study and document the communication protocol between the Upright GO V.1 and the mobile application.
- Create some open-source alternatives to the official mobile application.
- The Upright GO was first crowdfunded on Kickstarter in 2014, being first delivered to backers in mid-2016.
- Somewhere in 2018, the Upright GO V.1 was discontinued in favor of the Upright GO V.2, which has a slightly different design and features.
Disclaimer: This section, like the others, is primarily based on my personal experimentation with the device and research from various online sources. As a result, it may not be entirely accurate. If you have any corrections or suggestions, your input is welcome!
The Upright GO V.1 is built on top of the Texas Instruments CC2540 Bluetooth Low Energy (BLE) System-on-Chip (SoC). The device is powered by a 3.7V 115mAh LiPo battery, a 3-axis accelerometer to detect the user's posture, and a vibration motor to provide feedback to the user. For charging, the device provides a Micro-USB port, this port is used exclusively for charging the device and does not provide any data connectivity.
The Upright GO 1 was publicly released in at least two difference PCB versions: UR-01B-01A and UR-01C-01A. The main difference between the two versions is the accelerometer and the amplifiers used.
| PCB Version | Accelerometer | Amplifiers |
|---|---|---|
| UR-01C-01A | BMA250 or LIS2xx | INA 326 or INA2xx with/without MCP6001 |
| UR-01B-01A | ADXL362 | AD8426 |
Source: FCCID - Declaration Letter of Model Difference
The CC2540 SoC allows engineers to create a custom BLE profile used to communicate with other devices. The BLE profile is a set of rules that defines how the device and the mobile application communicate with each other.
The flashing of the CC2540 is done (frequently) using the TI CC Debugger and the SmartRF Flash Programmer software.
The CC2540 SoC is programmed using the Texas Instruments IAR Embedded Workbench, which is a prohibitly expensive commercial IDE that is used to develop and debug embedded applications.
More details on the CC2540 can be found in the CC2540 Datasheet.
As per some visual aalyzes of the device, the CC2540 SoC is connected to the following peripherals:
- Accelerometer: The components used are the BMA250 or LIS2xx for the UR-01C-01A PCB version and ADXL362 for the UR-01B-01A PCB version. All of these are 3-axis accelerometers. Component is located near the LED with a "387KA" inscription on it.
The PCB I have is one variation of the A model, and used a BMA250 accelerometer, so I can't tell for sure which version of the LIS2xx is used on the other variants of the A model.
- Flash Memory: There's a
FLASH_CSpin on the board, which is likely connected to the Flash Memory's Chip Select (CS) pin. I coudn't really identify the Flash memory in use.
The BLE communication between the Upright GO V.1 and the mobile application is done using the Generic Attribute Profile (GATT). The GATT profile is a hierarchical data structure and a standardized set of services and characteristics that defines how the BLE device will communicate.
Each GATT service has a unique 128-bit UUID that is used to identify the service. These GATT services are then divided into characteristics, which are used to exchange data between the device and the mobile application.
Characteristics are the "data" level of the hierarchy are the key to understand how BLE devices work in general, and thus we can use to reverse engineer the Upright GO V.1 and try to mimic the actions present in the official mobile application. For the sake of completeness, here's a brief overview of what can be done with characteristics:
- Read: The characteristic can be read by the client.
- Write: The characteristic can be written by the client.
- Notify: The characteristic can notify the client when the value changes.
The Characteristics 128-bit UUIDs are composed according to the following format:
0000XXXX-0000-1000-8000-00805f9b34fb, whereXXXXis the 16-bit UUID of the characteristic and0000-1000-8000-00805f9b34fbis BLE's standard base UUID.
So, characteristics can be understood similarly to what an endpoint is to a web API, where you can read, write, and subscribe to changes in the data (as a webhook or a WebSocket). We can use the characteristics to read and write data to the device.
The full, hardware-verified reference β organized by GATT service, with expected behaviors, byte formats, and the calibration/pause/telemetry lifecycles β lives in PROTOCOL.md. Quick summary of the key characteristics:
| UUID | Type | Description |
|---|---|---|
aab1 |
Write | \x01 calibrates: samples the wearer's current posture as the baseline, acks with a double vibration, and arms the device's slouch vibration. |
aab2 |
Read | Calibration state: \x00 not calibrated (always the case after a power cycle β the device never vibrates until recalibrated), \x02 calibrated. |
aab3 |
Read | Stored calibration record (not a live angle): two big-endian uint16s in deci-degrees, [baseline][threshold], threshold = baseline + 120 (+12Β°). |
aaca |
Notify/Read | Continuous absolute forward-tilt angle: uint16 little-endian, tenths of a degree (~200 upright β ~800 near-horizontal). Not a status byte. |
aac4 |
Notify/Read | Posture status: \x00 upright, \x01 slouched (grace period ~57 s), \x02 slouched + vibrating. (This is where "0x02 = slouching" actually lives.) |
aac3 |
Notify/Read | Worn sensor: \x01 worn, \x00 not worn. |
aac6 |
Notify/Read | Physical button: toggles \x01/\x00 per press. |
aac7 |
Notify/Read/Write | Training/Tracking mode toggle (\x01 = Tracking: sensing but no vibration β the official app's second mode, aka "pause"). Writable β an app can switch modes like a button press. |
aac9 |
Notify/Read | Per-minute telemetry byte: bit7 = currently slouched, bit6 = paused, low bits = slouch excursions in the last minute. Notifies every ~60 s. |
aad2 |
Notify/Read | Battery voltage, uint16 little-endian millivolts (single-cell LiPo, ~3550β4130 observed). Notifies every ~60 s. |
aaa2 |
Notify/Read | Charger connected: \x01/\x00. |
aad3 |
Write | Vibration motor: \x01 on, \x00 off. Strictly 1 byte; all other values are no-ops β no pattern/intensity interface exists. |
aad4 |
Write | Red LED: \x01 on (steady), \x00 off. |
aad6 |
Write | Green LED: \x01 on (blinks while on β firmware pattern), \x00 off. There is no aad5 and no blue LED (earlier versions of this table were wrong). |
Here's a simple Python script that uses the bleak library to interact with the Upright GO V.1 device. This script continuosly reads the current angle of the device and prints it to the console. Check the code-samples directory for more details.
import asyncio
from bleak import BleakClient
async def main():
address = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
characteristic_uuid = "0000aac6-0000-1000-8000-00805f9b34fb"
def notification_handler(sender, data):
print(f"Notification from {sender}: {data}")
async with BleakClient(address) as client:
await client.start_notify(characteristic_uuid, notification_handler)
print(f"Subscribed to notifications from {characteristic_uuid}")
await asyncio.sleep(3000)
await client.stop_notify(characteristic_uuid)
if __name__ == "__main__":
asyncio.run(main())Some internal photos of the device can be found in FFCID website but they seem to represent an early verison of the device that uses a few different components compared to the versions mentioned in the PCB Versions section.
All of the following tasks are subject to change as I continue to explore the device and are not in any particular order. By the way, feel free to suggest new tasks, improvements, or contribute.
- Write the first draft of the README.
- Create a more detailed characteristics table. β PROTOCOL.md (2026-07: complete map, all characteristics decoded or catalogued)
- Create a minimalistic Python library to interact with the device from a computer.
- Create a mobile application to interact with the device. β Open Posture Companion (React Native / Expo)
- Identify the location of the accelerometer on the device. (thanks to /u/freaggle_70)
If you would like to contribute to this project, please feel free to open an issue or a pull request. I would be happy to collaborate with you!
This project is meant to be free and acessible, all contributions are welcome and will be credited.
This project was created by Nilton Heck and is licensed under the MIT License.
Thanks for the folks from /r/AskElectronics for kindly helping me to identify some of the components used on the device:
This project is not affiliated with Upright GO, Texas Instruments, or any other company. The information provided here is for educational purposes only and should not be used for any commercial purposes.
Even though I encourage the use of this information to create some open-source alternatives to the official mobile application, I do not condone the use of this information to create counterfeit devices or to infringe on any intellectual property rights. Please respect the rights of the original creators.


