Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sh367601-uart

Reading a Sinowealth SH367601x battery protection IC (SH3676010 / 3676014 / 3676016) over its UART: the protocol, the CRC, an Arduino Uno bridge, a command-line reader and a live web dashboard.

If you have a cheap 6S to 16S "smart" protection board with an unmarked three-pad header and an SH36760xx chip on it, this is for you. There was no working public code for this chip when we started.

7S board with the SH3676016 and the three unmarked pads

TL;DR

Interface UART only, 9600 baud, 8N1, 5 V logic. The chip has no I2C.
Address fixed 0x1C
Read RAM 1C 03 <reg> <n> <crc> -> 1C 03 5A <reg> <n> <data...> <crc>
Read EEPROM 1C 02 <reg> <n> <crc>
CRC8 poly 0x07, init 0x00, over every byte incl. the address
Wake-up send a dummy 0x00 first; the UART block sleeps after 1 s of silence
The three pads GND, TXD (chip output, driven hard high), RXD (chip input, weak pull-up)
Gotcha EEPROM is rated for 100 write cycles total

Full register maps and formulas: docs/protocol.md.

Quick start

Hardware: an Arduino Uno (5 V logic matches the chip) and three wires.

Uno BMS pad
GND GND
A5 chip TXD
A4 chip RXD

If you do not know which pad is which, wire them either way. The bridge can swap the roles in software.

# flash the bridge (or open the .ino in the Arduino IDE)
arduino-cli compile --fqbn arduino:avr:uno arduino_uart_bridge
arduino-cli upload  --fqbn arduino:avr:uno -p /dev/ttyACM0 arduino_uart_bridge

# one-shot decoded dump: cells, current, temperatures, status, EEPROM thresholds
python3 arduino_uart_bridge/sh367601_host.py /dev/ttyACM0 dump

# live dashboard on http://localhost:8080/
python3 arduino_uart_bridge/bms_web.py

No Python packages are needed; the host side talks to the Uno with plain termios. If dump prints no reply, run python3 arduino_uart_bridge/sh367601_host.py /dev/ttyACM0 orient 0 once to swap TXD/RXD and try again.

What you get

  • arduino_uart_bridge/arduino_uart_bridge.ino - software-serial bridge on A4/A5, sends the wake byte, forwards raw frames, returns raw replies. Orientation switchable at runtime.
  • arduino_uart_bridge/sh367601.py - protocol, CRC, register decoding, conversions.
  • arduino_uart_bridge/sh367601_host.py - CLI: dump, ram <reg> <n>, eeprom <reg> <n>, orient 0|1.
  • arduino_uart_bridge/bms_web.py + static/index.html - dashboard: live tiles, history charts with hover, per-cell plot against the chip's own thresholds, decoded protection settings, session Ah/Wh, a voltage/coulomb-count state-of-charge estimate, CSV logging, dark mode. Standard library only.

dashboard

The story: how the pads were identified

This took a whole day, and the detours are the useful part.

  1. A look-alike board said SDA/SCL. A similar board from the same family of products has its three pads silk-screened GND SCL SDA, so we assumed I2C. Wrong: that board uses a different chip. The SH367601x has no I2C at all. Always find the datasheet for your chip.
  2. An FT232R could not pull one line low. Bit-banging I2C on the FTDI adapter (open-drain emulated by toggling pin direction, see dead-ends/ftdi/) showed one adapter pin stuck high whatever we did. In hindsight that pin was on the chip's TXD, a push-pull output driven high. A UART output cannot be pulled low by an open-drain master. This was the first real clue and we misread it.
  3. Random ACKs from an I2C scan mean a floating wire. An Arduino Wire scan returned different "devices" on every pass. That is not a bus, that is noise. A bad solder joint on one wire caused it; after reflowing, the scan went clean and empty, as it should for a chip with no I2C.
  4. Rise times told the pins apart. Driving each line low from the Uno and timing the recovery: one line rose in 4 us (a strong driver or stiff pull-up), the other in 44 us (a weak pull-up). The fast one is TXD, the slow one is RXD. Cheap to measure, very informative.
  5. The only public driver had the wrong opcode. A GitHub snippet for this chip used 0x01 for reads and admitted its address was a guess. The datasheet says 0x02 (EEPROM) and 0x03 (RAM) with a length byte, and 0x01 is write. The first correct frame answered immediately.
  6. The wake byte matters. In power-down the UART block is off until it sees a falling edge on RXD. Without a dummy byte first, a perfectly formed frame is ignored.

RSW1 wake switch pads and the unpopulated 2x2 footprint four R001 shunts in parallel = 0.25 mOhm, and the MOSFET bank

Board notes (7S, 24 V 12 Ah pack)

  • Shunt: four R001 in parallel = 0.25 mOhm. With that, one step of the current register is 13.7 mA, but the register only moves in steps of 8, so expect ~0.11 A resolution.
  • Current sign: positive = charging, negative = discharging (verified with a charger and a load).
  • RSW1 two-hole footprint = wake/reset switch input. Bridging it for a second wakes the chip.
  • EEPROM on this board: OV 4.250 V / 0.2 s, OV release 4.15 V, UV 2.70 V / 0.5 s, UV release 2.90 V, balancing from 4.18 V, 7 cells.

What the chip can and cannot do

It is a protection IC, not a controller. The MOSFETs are on/off switches: no current limiting, no PWM, no output regulation. Adjustable via EEPROM: cell count, over/undervoltage thresholds and delays, balance start voltage, overcurrent and short-circuit thresholds, temperature limits, release behaviour. There is no "switch output off" command; the CTLD pin does that in hardware, and the EEPROM write-enable sequence turns the MOSFETs off as a side effect. Writing tools are deliberately not included here because of the 100-cycle limit.

Dead ends, kept on purpose

dead-ends/ holds the FTDI bit-bang I2C master and the Arduino I2C bridge. They work as I2C tools; they just cannot find a device that does not exist. They are kept because the diagnostics inside them (rise-time test, both-orientation scan, analog line levels) are what eventually solved this.

Datasheet

SH367601X CV1.0A, Sinowealth. It is copyrighted and not redistributed here. Section 11 covers the UART, 10.2 the conversions, 13 the register maps.

License

MIT, see LICENSE.

About

Reading a Sinowealth SH367601x (SH3676010/14/16) BMS over its UART: protocol, CRC, Arduino bridge and live dashboard

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages