This page documents the I2C packet structure and communication patterns observed in the Shrooly device through reverse engineering efforts.
Overview
The Shrooly device uses I2C (Inter-Integrated Circuit) communication for interfacing with various sensors and peripherals. The main microcontroller communicates with a co-processor that handles specialized functions.
Register Structure
Capacitive Sensor Registers
The system continuously polls five 32-bit registers that appear to represent capacitive sensors:
Register Address | Size | Purpose | Notes |
---|---|---|---|
0x03 | 32-bit | Capacitive Sensor 1 | Last 2 bytes always 0x00 |
0x07 | 32-bit | Capacitive Sensor 2 | Last 2 bytes always 0x00 |
0x0B | 32-bit | Capacitive Sensor 3 | Last 2 bytes always 0x00 |
0x0F | 32-bit | Capacitive Sensor 4 | Last 2 bytes always 0x00 |
0x13 | 32-bit | Capacitive Sensor 5 | Last 2 bytes always 0x00 |
Status Register
Register Address | Size | Purpose | Typical Values |
---|---|---|---|
0x01 | 16-bit | Status/Mode | 0x14-0x15 (normal), 0x49-0x4B (peak) |
Communication Patterns
Polling Sequence
The device follows a regular polling pattern:
- Read status register (0x01)
- Read all five capacitive sensor registers sequentially
- Process data
- Repeat cycle
Data Format
Each 32-bit register read returns 4 bytes:
- Bytes 0-1: Sensor data (variable)
- Bytes 2-3: Always 0x0000 (padding or reserved)
Example read sequence:
Read 0x03: [0xA2, 0x15, 0x00, 0x00]
Read 0x07: [0xB1, 0x14, 0x00, 0x00]
Read 0x0B: [0xC0, 0x16, 0x00, 0x00]
Read 0x0F: [0xA8, 0x15, 0x00, 0x00]
Read 0x13: [0x9F, 0x14, 0x00, 0x00]
Observed Behaviors
Humidifier Control
When the humidifier state changes, specific patterns appear in the I2C communication:
Humidifier Turn On:
- Status register may show elevated values
- Increased activity on certain sensor channels
- Possible command sequence preceding activation
Humidifier Turn Off:
- Return to baseline status values
- Sensor readings stabilize
- Confirmation pattern in communication
Sensor Applications
The five capacitive sensors likely monitor:
- Water level in reservoir
- Touch interface buttons
- Presence detection
- Humidity sensing assistance
- Safety/overflow detection
Technical Details
I2C Configuration
- Speed: Standard mode (100 kHz) or Fast mode (400 kHz)
- Addressing: 7-bit addressing mode
- Pull-up Resistors: Required on SDA and SCL lines
Co-processor
The device includes a secondary processor (possibly Raspberry Pi-based) that handles:
- Capacitive sensor processing
- Water level monitoring
- Safety functions
- Touch interface management
Unresolved Questions
Several aspects of the I2C communication remain unclear:
- Command Structure: How are commands sent to control outputs?
- Initialization Sequence: What sequence properly initializes the co-processor?
- Extended Registers: Are there additional registers beyond those observed?
- Error Handling: How does the system handle I2C communication errors?
Implementation Notes
When implementing I2C communication:
// Example pseudo-code for reading sensor data
uint32_t read_capacitive_sensor(uint8_t register_addr) {
uint8_t data[4];
i2c_read_register(DEVICE_ADDR, register_addr, data, 4);
// Note: Last 2 bytes are always 0x00
return (data[0] | (data[1] << 8));
}
// Poll all sensors
void poll_sensors() {
uint16_t status = read_status_register(0x01);
uint16_t sensors[5];
sensors[0] = read_capacitive_sensor(0x03);
sensors[1] = read_capacitive_sensor(0x07);
sensors[2] = read_capacitive_sensor(0x0B);
sensors[3] = read_capacitive_sensor(0x0F);
sensors[4] = read_capacitive_sensor(0x13);
process_sensor_data(status, sensors);
}
Contributing
If you’ve discovered additional I2C communication patterns or decoded more of the protocol, please share your findings on the GitHub repository.
References
- Original reverse engineering thread
- CAP1206 Touch Sensor Datasheet
- ESP32-S3 I2C Documentation