Adding a data interface to the Omron BF511/HBF-511B-E scale
- Intro
- Reverse engineering
- Data analysis
- Building a proof-of-concept
- Pinout
- Position of BF511 pins
- Example code (Arduino Uno Rev.3)
I bought the Omron BF511 for ~50 euros back in ~2019 and found it to be a really good scale. The only grief: It did not have any interface to use it for automatic data transfer and tracking. I found the very nice openScale project and got inspired to get some kind of data interface into this scale. From the start I thought I had three options, with growing difficulty and effort:
- Finding a debug interface which might already output all data
- Finding some kind of memory that might be read
- Tapping directly into the LCD driver, tracking and "OCRing" the display state
The ultimate option would be to understand how the scale works and doing all logic by myself but I thought this to be a bit too much and I hoped for a simpler solution.
Opening up the scale base shows that it only contains a base board with an NEC µPC324 Low Power Quad Operational Amplifier (NEC C324G), a 4x AA battery holder and the weight cells integrated into the feet. The base is connected to the handheld via the CN1 connector, which transfers the "data" of the weight cells plus raw power up via a spiral cable. The base also contains a lot of rust, because it seems to be made from steel. But nothing what some muscle and sandpaper couldn't solve.
Opening up the scale handheld reveals the actual brains of the operation, the "back" which contains the MCU, some power supplies, CN1 connector as well as the back which houses an I2C EEPROM, buttons and LCD.
The MCU is an Renesas H8/38327, which includes an LCD controller, ROM and two SCI3 (serial communication interface) drivers which can "speak" among other things serial and SPI. As CN1 delivers the raw voltage to the handheld, one can receive 6 V (4x fresh AA alkaline batteries with 1.5 V) or 4.8 V (4x AA NiMH akkus or similar). A voltage regulator drives the power down to 4 V, which is the exact power the MCU needs. A quick probe of both serial interfaces show that SCI3-2 on CPU pins 69-72 has no connection at all, SCI3-1 on CPU pins 21-23 however seems to have some kind of data flow. Analyzing SCI3-1 connections via Sigrok/fx2lafw probe does not give any conclusive evidence, pulses can be seen, but not correctly identified.
With this information, the quick win of having a debug interface which might reveal all data was already gone.
Turning the board to the backside and looking at it, we can identify the EEPROM to be a S24CS08AVGY alias S-24CS08A in 8 PIN SOP format. This is an 2-Wire CMOS Serial EEPROM which works between 1.8 V and 5.5 V.
After some diagnosis following information can be found:
- This I2C EEPROM is connected to SCI3-1 and its SDA/SCL interface is pulled up to 4 V
- There are several resistors in place to connect between the MCU and EEPROM
- The WP/WriteProtect pin of the EEPROM is actually used by the MCU and write protection is always in place except if the scale saves data
- Access is done via a 7 bit code:
- Main address is 1010
- followed by the pins A0-A2
- ... and the last bit is a read/write bit
- A0-A2 are pulled depending on which page is to be written
- bitSize: 8 Kbits
- Size: 1024 Bytes
- 16 bytes/page
A quick i2c scan with an Arduino Uno (as being 5 V tolerant) quickly identifies the chip:
Found device at address 84 (0x54)
Found device at address 85 (0x55)
Found device at address 86 (0x56)
Found device at address 87 (0x57)
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- 54 55 56 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
After connecting the I2C bus to GND and SDA/SCL of an CH341A in parallel mode (here: CJMCU-341, but any other CH431A unit would have worked) and using NeoProgrammer with the following settings allowed to dump the EEPROM
Notice the start of the EEPROM with "HBF511", identifying the type of scale used. I presume 3100 might be some program/schema version.
Examining the extracted data in ImHex revealed patters close at the end of the EEPROM: 4 slots, each 26 bytes in length:
All data is saved in little endian format, most of it as uint16. The cells just need to be read and formatted correctly, e.g. some uint16 calibrated to float and divided by 100.
The example data and table can also be found in the data folder.
This proof of concept is built with an RAK3172, as this consists of an STM32LE5/STM32WLE5CCU6 SoC which combines an ARM MCU with a LoRA radio. The chip is an ultra low-power system and is 5 V tolerant, which allows us to create this PoC without needing bi-directional logic-level conversion.
Analysis data and system design of the BF511 further revealed a good method to automatically extract data: As soon as the LCD is turned out (on start of the scale), CPU pin 30/V1 is driven high to 3.33 V - and falls back to 0 V when the scale shuts down. The shutdown (falling edge of V1) informs us that a) potentially new data has been saved to the EEPROM, b) it is now save to access the EEPROM as the MCU is switched off.
The PoC works as follows: RAK3172 is directly powered via LDO to the raw VCC/GND of the BF511. RAK3172 goes into deep sleep and listens to V1 for a falling edge, informing it that the scale was on and has now been shutdown. RAK3172 awakens, reads EEPROM at the desired data slot and sends data via LoRA modem.
As this setup is a bit to complicated and might not fall into the easier use-case with openScale, the use with an Arduino Uno Rev.3 is shown here. As a 5 V device it can be used to extract data without logic level conversion. I did not implement the wake-up trigger in this use-case and powered the Uno via USB, the source code will be shown later.
| BF511 pin | voltage level | connect (STM32) | connect (Uno Rev3) |
|---|---|---|---|
| Back: TP30/VCC | ~4.8 V - 6 V | LDO Input | / |
| Back: TP19/CPU pin 30/V1 | 3.33 V | PB3 / PB_3 / D17/A0 | / |
| Back: TP32/GND (or EEPROM GND) | 0 V | LDO GND | GND |
| Front: EEPROM GND (or TP32 GND) | 0 V | LDO GND | GND |
| Front: EEPROM SDA | 4 V | PA_11 / D11/A7 - I2C_SDA | A4 |
| Front: EEPROM SCL | 4 V | PA_12 / D12/A8 - I2C_SCL | A5 |
An example code for extracting data with an Arduino Uno Rev.3 can also be found in data/WireTransferUno.ino.












