A drop-in replacement for smbus-cffi/smbus-python in pure Python
npx @tessl/cli install tessl/pypi-smbus2@0.5.00
# smbus2
1
2
A drop-in replacement for smbus-cffi/smbus-python in pure Python. smbus2 provides a complete implementation of the SMBus (System Management Bus) protocol for I2C communication, enabling comprehensive device interaction for embedded systems, IoT devices, and hardware interfacing applications.
3
4
## Package Information
5
6
- **Package Name**: smbus2
7
- **Language**: Python
8
- **Installation**: `pip install smbus2`
9
10
## Core Imports
11
12
```python
13
from smbus2 import SMBus, i2c_msg, I2cFunc
14
```
15
16
Individual component import:
17
18
```python
19
from smbus2 import SMBus # Main SMBus interface
20
from smbus2 import i2c_msg # I2C message class for combined transactions
21
from smbus2 import I2cFunc # I2C functionality flags enum
22
```
23
24
## Basic Usage
25
26
```python
27
from smbus2 import SMBus
28
29
# Basic usage with context manager (recommended)
30
with SMBus(1) as bus:
31
# Read a byte from address 0x50, register 0x00
32
data = bus.read_byte_data(0x50, 0x00)
33
print(f"Read value: {data}")
34
35
# Write a byte to address 0x50, register 0x00
36
bus.write_byte_data(0x50, 0x00, 0xFF)
37
38
# Manual connection management
39
bus = SMBus(1) # Open I2C bus 1
40
try:
41
# Read word data from register
42
word_data = bus.read_word_data(0x50, 0x10)
43
print(f"Word data: {word_data}")
44
finally:
45
bus.close() # Always close the connection
46
47
# Enable Packet Error Checking (PEC)
48
with SMBus(1) as bus:
49
bus.pec = 1 # Enable PEC
50
data = bus.read_byte_data(0x50, 0x00)
51
```
52
53
## Architecture
54
55
smbus2 is built on a layered architecture:
56
57
- **SMBus Class**: High-level interface providing all standard SMBus operations
58
- **i2c_msg System**: Low-level message system for combined I2C transactions beyond SMBus limitations
59
- **ctypes Integration**: Direct interface to Linux I2C subsystem via ioctl calls
60
- **Pure Python Implementation**: No external dependencies, compatible across Python versions
61
62
The library supports both traditional SMBus operations (limited to 32 bytes) and advanced I2C transactions (unlimited size) through the i2c_rdwr interface, making it suitable for both simple sensor communication and complex data transfer scenarios.
63
64
## Capabilities
65
66
### Connection Management
67
68
SMBus connection initialization, opening, and closing with support for context managers and manual resource management.
69
70
```python { .api }
71
class SMBus:
72
def __init__(self, bus=None, force=False):
73
"""
74
Initialize SMBus instance.
75
76
Parameters:
77
- bus: int or str, I2C bus number (e.g. 1) or device path (e.g. '/dev/i2c-1')
78
- force: bool, force using slave address even when driver is already using it
79
"""
80
81
def __enter__(self):
82
"""Context manager entry, returns self."""
83
84
def __exit__(self, exc_type, exc_val, exc_tb):
85
"""Context manager exit, closes connection."""
86
87
def open(self, bus):
88
"""
89
Open I2C bus connection.
90
91
Parameters:
92
- bus: int or str, I2C bus number or device path
93
94
Raises:
95
- TypeError: if bus type is not int or str
96
"""
97
98
def close(self):
99
"""Close I2C connection."""
100
```
101
102
### Basic SMBus Operations
103
104
Fundamental SMBus operations including quick commands and single byte read/write operations.
105
106
```python { .api }
107
def write_quick(self, i2c_addr, force=None):
108
"""
109
Perform SMBus Quick Command.
110
111
Parameters:
112
- i2c_addr: int, I2C slave address
113
- force: bool, optional override for force flag
114
115
Raises:
116
- IOError: if operation fails
117
"""
118
119
def read_byte(self, i2c_addr, force=None):
120
"""
121
Read single byte from I2C device.
122
123
Parameters:
124
- i2c_addr: int, I2C slave address
125
- force: bool, optional override for force flag
126
127
Returns:
128
- int: byte value (0-255)
129
"""
130
131
def write_byte(self, i2c_addr, value, force=None):
132
"""
133
Write single byte to I2C device.
134
135
Parameters:
136
- i2c_addr: int, I2C slave address
137
- value: int, byte value to write (0-255)
138
- force: bool, optional override for force flag
139
"""
140
```
141
142
### Register-Based Operations
143
144
SMBus byte and word data operations for reading from and writing to specific device registers.
145
146
```python { .api }
147
def read_byte_data(self, i2c_addr, register, force=None):
148
"""
149
Read byte from specified register.
150
151
Parameters:
152
- i2c_addr: int, I2C slave address
153
- register: int, register address (0-255)
154
- force: bool, optional override for force flag
155
156
Returns:
157
- int: byte value from register
158
"""
159
160
def write_byte_data(self, i2c_addr, register, value, force=None):
161
"""
162
Write byte to specified register.
163
164
Parameters:
165
- i2c_addr: int, I2C slave address
166
- register: int, register address (0-255)
167
- value: int, byte value to write (0-255)
168
- force: bool, optional override for force flag
169
"""
170
171
def read_word_data(self, i2c_addr, register, force=None):
172
"""
173
Read 16-bit word from specified register.
174
175
Parameters:
176
- i2c_addr: int, I2C slave address
177
- register: int, register address (0-255)
178
- force: bool, optional override for force flag
179
180
Returns:
181
- int: 16-bit word value from register
182
"""
183
184
def write_word_data(self, i2c_addr, register, value, force=None):
185
"""
186
Write 16-bit word to specified register.
187
188
Parameters:
189
- i2c_addr: int, I2C slave address
190
- register: int, register address (0-255)
191
- value: int, 16-bit word value to write (0-65535)
192
- force: bool, optional override for force flag
193
"""
194
```
195
196
### Process Call Operations
197
198
SMBus Process Call operations for atomic write-then-read transactions.
199
200
```python { .api }
201
def process_call(self, i2c_addr, register, value, force=None):
202
"""
203
Execute SMBus Process Call (write 16-bit value, read 16-bit response).
204
205
Parameters:
206
- i2c_addr: int, I2C slave address
207
- register: int, register address
208
- value: int, 16-bit value to send
209
- force: bool, optional override for force flag
210
211
Returns:
212
- int: 16-bit response value
213
"""
214
215
def block_process_call(self, i2c_addr, register, data, force=None):
216
"""
217
Execute SMBus Block Process Call (write block, read block response).
218
219
Parameters:
220
- i2c_addr: int, I2C slave address
221
- register: int, register address
222
- data: list of int, data bytes to send (max 32 bytes)
223
- force: bool, optional override for force flag
224
225
Returns:
226
- list of int: response data bytes
227
228
Raises:
229
- ValueError: if data length exceeds 32 bytes
230
"""
231
```
232
233
### Block Data Operations
234
235
SMBus block data operations for reading and writing multiple bytes in a single transaction.
236
237
```python { .api }
238
def read_block_data(self, i2c_addr, register, force=None):
239
"""
240
Read block of data from register (up to 32 bytes).
241
242
Parameters:
243
- i2c_addr: int, I2C slave address
244
- register: int, start register address
245
- force: bool, optional override for force flag
246
247
Returns:
248
- list of int: data bytes read
249
"""
250
251
def write_block_data(self, i2c_addr, register, data, force=None):
252
"""
253
Write block of data to register (up to 32 bytes).
254
255
Parameters:
256
- i2c_addr: int, I2C slave address
257
- register: int, start register address
258
- data: list of int, data bytes to write (max 32 bytes)
259
- force: bool, optional override for force flag
260
261
Raises:
262
- ValueError: if data length exceeds 32 bytes
263
"""
264
265
def read_i2c_block_data(self, i2c_addr, register, length, force=None):
266
"""
267
Read I2C block data with specified length.
268
269
Parameters:
270
- i2c_addr: int, I2C slave address
271
- register: int, start register address
272
- length: int, number of bytes to read (max 32)
273
- force: bool, optional override for force flag
274
275
Returns:
276
- list of int: data bytes read
277
278
Raises:
279
- ValueError: if length exceeds 32 bytes
280
"""
281
282
def write_i2c_block_data(self, i2c_addr, register, data, force=None):
283
"""
284
Write I2C block data.
285
286
Parameters:
287
- i2c_addr: int, I2C slave address
288
- register: int, start register address
289
- data: list of int, data bytes to write (max 32 bytes)
290
- force: bool, optional override for force flag
291
292
Raises:
293
- ValueError: if data length exceeds 32 bytes
294
"""
295
```
296
297
### Advanced I2C Operations
298
299
Combined I2C read/write operations using i2c_msg for transactions beyond SMBus limitations.
300
301
```python { .api }
302
def i2c_rdwr(self, *i2c_msgs):
303
"""
304
Execute combined I2C read/write operations with repeated start.
305
306
Parameters:
307
- i2c_msgs: i2c_msg instances created with i2c_msg.read() or i2c_msg.write()
308
309
Note: Allows bulk transfers beyond SMBus 32-byte limit
310
"""
311
312
class i2c_msg:
313
"""I2C message for combined transactions."""
314
315
@staticmethod
316
def read(address, length):
317
"""
318
Create I2C read message.
319
320
Parameters:
321
- address: int, I2C slave address
322
- length: int, number of bytes to read
323
324
Returns:
325
- i2c_msg: configured for read operation
326
"""
327
328
@staticmethod
329
def write(address, buf):
330
"""
331
Create I2C write message.
332
333
Parameters:
334
- address: int, I2C slave address
335
- buf: list of int or str, data to write
336
337
Returns:
338
- i2c_msg: configured for write operation
339
"""
340
341
def __iter__(self):
342
"""Iterate over message data bytes."""
343
344
def __len__(self):
345
"""Get message length."""
346
347
def __bytes__(self):
348
"""Get message data as bytes."""
349
350
def __repr__(self):
351
"""String representation of message."""
352
353
def __str__(self):
354
"""Decoded string representation of message data."""
355
356
# Properties
357
addr: int # I2C slave address
358
flags: int # Message flags (e.g., I2C_M_RD for read)
359
len: int # Message length in bytes
360
buf: pointer # Message data buffer
361
```
362
363
### Configuration and Capabilities
364
365
Device capability detection and configuration management including Packet Error Checking.
366
367
```python { .api }
368
def enable_pec(self, enable=True):
369
"""
370
Enable or disable Packet Error Checking (SMBus 1.1+).
371
372
Parameters:
373
- enable: bool, True to enable PEC, False to disable
374
375
Raises:
376
- IOError: if device doesn't support PEC
377
"""
378
379
# Properties
380
pec: int # PEC setting (0=disabled, 1=enabled)
381
funcs: I2cFunc # Device capability flags
382
fd: int # File descriptor for I2C device
383
address: int # Current I2C slave address
384
force: bool # Force flag setting
385
386
class I2cFunc:
387
"""IntFlag enum for I2C/SMBus capability flags."""
388
389
# Basic I2C capabilities
390
I2C = 0x00000001
391
ADDR_10BIT = 0x00000002
392
PROTOCOL_MANGLING = 0x00000004
393
SMBUS_PEC = 0x00000008
394
NOSTART = 0x00000010
395
SLAVE = 0x00000020
396
397
# SMBus operation capabilities
398
SMBUS_QUICK = 0x00010000
399
SMBUS_READ_BYTE = 0x00020000
400
SMBUS_WRITE_BYTE = 0x00040000
401
SMBUS_READ_BYTE_DATA = 0x00080000
402
SMBUS_WRITE_BYTE_DATA = 0x00100000
403
SMBUS_READ_WORD_DATA = 0x00200000
404
SMBUS_WRITE_WORD_DATA = 0x00400000
405
SMBUS_PROC_CALL = 0x00800000
406
SMBUS_READ_BLOCK_DATA = 0x01000000
407
SMBUS_WRITE_BLOCK_DATA = 0x02000000
408
SMBUS_READ_I2C_BLOCK = 0x04000000
409
SMBUS_WRITE_I2C_BLOCK = 0x08000000
410
SMBUS_BLOCK_PROC_CALL = 0x00008000
411
SMBUS_HOST_NOTIFY = 0x10000000
412
413
# Combined capability flags
414
SMBUS_BYTE = 0x00060000
415
SMBUS_BYTE_DATA = 0x00180000
416
SMBUS_WORD_DATA = 0x00600000
417
SMBUS_BLOCK_DATA = 0x03000000
418
SMBUS_I2C_BLOCK = 0x0c000000
419
SMBUS_EMUL = 0x0eff0008
420
```
421
422
## Usage Examples
423
424
### Basic Sensor Reading
425
426
```python
427
from smbus2 import SMBus
428
429
# Read temperature from sensor at address 0x48
430
with SMBus(1) as bus:
431
# Read 2-byte temperature value
432
temp_raw = bus.read_word_data(0x48, 0x00)
433
# Convert to Celsius (example conversion for specific sensor)
434
temperature = (temp_raw >> 8) * 0.5
435
print(f"Temperature: {temperature}°C")
436
```
437
438
### Block Data Transfer
439
440
```python
441
from smbus2 import SMBus
442
443
# Read configuration block from EEPROM
444
with SMBus(1) as bus:
445
# Read 16 bytes starting from address 0x00
446
config_data = bus.read_i2c_block_data(0x50, 0x00, 16)
447
print(f"Config: {[hex(b) for b in config_data]}")
448
449
# Write new configuration
450
new_config = [0x01, 0x02, 0x03, 0x04, 0x05]
451
bus.write_i2c_block_data(0x50, 0x00, new_config)
452
```
453
454
### Combined I2C Transactions
455
456
```python
457
from smbus2 import SMBus, i2c_msg
458
459
# Advanced I2C operations beyond SMBus limits
460
with SMBus(1) as bus:
461
# Write command and read large response in single transaction
462
write_cmd = i2c_msg.write(0x40, [0x01, 0x02])
463
read_response = i2c_msg.read(0x40, 64) # Read 64 bytes
464
465
bus.i2c_rdwr(write_cmd, read_response)
466
467
# Access response data
468
response_data = list(read_response)
469
print(f"Response: {response_data}")
470
```
471
472
### Capability Detection
473
474
```python
475
from smbus2 import SMBus, I2cFunc
476
477
with SMBus(1) as bus:
478
# Check device capabilities
479
if bus.funcs & I2cFunc.SMBUS_PEC:
480
print("Device supports Packet Error Checking")
481
bus.pec = 1 # Enable PEC
482
483
if bus.funcs & I2cFunc.SMBUS_BLOCK_DATA:
484
print("Device supports SMBus block operations")
485
486
if bus.funcs & I2cFunc.I2C:
487
print("Device supports I2C operations")
488
```
489
490
## Constants
491
492
```python { .api }
493
# I2C device control constants
494
I2C_SLAVE = 0x0703 # Use this slave address
495
I2C_SLAVE_FORCE = 0x0706 # Use this slave address, even if already in use by a driver
496
I2C_FUNCS = 0x0705 # Get the adapter functionality mask
497
I2C_RDWR = 0x0707 # Combined R/W transfer (one STOP only)
498
I2C_SMBUS = 0x0720 # SMBus transfer. Takes pointer to i2c_smbus_ioctl_data
499
I2C_PEC = 0x0708 # != 0 to use PEC with SMBus
500
501
# SMBus transfer direction markers
502
I2C_SMBUS_WRITE = 0
503
I2C_SMBUS_READ = 1
504
505
# SMBus operation size identifiers
506
I2C_SMBUS_QUICK = 0
507
I2C_SMBUS_BYTE = 1
508
I2C_SMBUS_BYTE_DATA = 2
509
I2C_SMBUS_WORD_DATA = 3
510
I2C_SMBUS_PROC_CALL = 4
511
I2C_SMBUS_BLOCK_DATA = 5 # Not supported by Pure-I2C drivers with SMBUS emulation
512
I2C_SMBUS_BLOCK_PROC_CALL = 7 # Not supported by Pure-I2C drivers either
513
I2C_SMBUS_I2C_BLOCK_DATA = 8
514
I2C_SMBUS_BLOCK_MAX = 32
515
516
# I2C message flags
517
I2C_M_RD = 0x0001
518
```
519
520
## Error Handling
521
522
Common exceptions that may be raised:
523
524
- **IOError**: I2C operation failed (device not responding, bus error, insufficient permissions, PEC not supported)
525
- **ValueError**: Invalid parameter values (data length exceeds I2C_SMBUS_BLOCK_MAX (32 bytes), invalid length specification)
526
- **TypeError**: Incorrect parameter types (bus must be int or str)
527
528
Specific error conditions:
529
- Block operations raise `ValueError` if data length > 32 bytes
530
- `enable_pec()` raises `IOError` if device doesn't support SMBUS_PEC functionality
531
- `open()` raises `TypeError` if bus parameter is not int or str
532
533
Always use try-except blocks for robust error handling:
534
535
```python
536
from smbus2 import SMBus, I2cFunc
537
538
try:
539
with SMBus(1) as bus:
540
# Check PEC support before enabling
541
if bus.funcs & I2cFunc.SMBUS_PEC:
542
bus.pec = 1
543
data = bus.read_byte_data(0x50, 0x00)
544
except IOError as e:
545
print(f"I2C communication error: {e}")
546
except ValueError as e:
547
print(f"Invalid parameter: {e}")
548
except TypeError as e:
549
print(f"Invalid type: {e}")
550
```