SMBus compatible class
Usage
This is a smbus compatibility class. You can use it to run any I2C Python library for Raspberry Pi or micropython just using MCP2221’s I2C device interface.
Usage:
from EasyMCP2221 import SMBus
bus = SMBus()
or
from EasyMCP2221 import smbus
bus = smbus.SMBus()
Note
To use other mcp functions in addition to SMBus, do not create a new MCP Device.
It will interfere with existing bus resulting in unpredictable behavior.
Always re-use bus.mcp
object (see example 2).
Example 1: Basic weather station
In this example, we are using a library from Pimoroni/BME280 to read Temperature, Barometric Pressure and Relative Humidity from a BME280 sensor.
That library is designed for Raspberry Pi or any other system that supports SMBus protocol. It works together with EasyMCP2221 via SMBus class.
Install:
pip install pimoroni-bme280 EasyMCP2221
Example code:
import time
from EasyMCP2221 import SMBus
from bme280 import BME280
bus = SMBus(1)
bme280 = BME280(i2c_dev=bus)
while True:
temperature = bme280.get_temperature()
pressure = bme280.get_pressure()
humidity = bme280.get_humidity()
print('{:05.2f}*C {:05.2f}hPa {:05.2f}%'.format(temperature, pressure, humidity))
time.sleep(1)
Output:
17.93*C 933.76hPa 51.57%
17.92*C 933.76hPa 51.57%
17.91*C 933.77hPa 51.53%
17.91*C 933.77hPa 51.50%
17.91*C 933.77hPa 51.54%
...
Example 2: Real Time Clock with LCD
This is a digital clock with two I2C chips:
DS1307 as RTC
LCD display based on with PCF8574 I2C adapter.
It also shows how to re-use mcp
object to further configure MCP2221.
Main loop:
DS1307 is configured as 1Hz square oscillator.
MCP2221’s GP2 is configured as Interrupt on Change.
The rising edge of DS1307’s output triggers the update cycle.
Full code on EasyMCP2221 examples/clock
from EasyMCP2221 import SMBus
from lcd_driver import LCD
from DS1307 import DS1307
# Create SMBus and instances
bus = SMBus()
lcd = LCD(bus, addr=0x3F)
ds = DS1307(bus, addr=0x68)
bus.mcp.I2C_speed(100_000) # DS1307 only supports 100kHz
bus.mcp.set_pin_function(
gp0 = "GPIO_IN", # unused
gp1 = "IOC", # trigger update LCD each second
gp2 = "DAC", # simulate backup battery
gp3 = "LED_I2C") # i2c traffic indicator
bus.mcp.DAC_write(21) # about 3.28V with 5V Vcc
bus.mcp.IOC_config(edge = "rising")
# Initialization after a complete power loss
if ds.halted():
ds.write_now()
ds._write(0x07, 0b0001_0000) # sqwe 1Hz
print("RTC initialized with current timestamp")
else:
print("RTC was already initialized")
lcd.clear()
# Update only when GP1 changes using Interrupt On Change
while True:
if bus.mcp.IOC_read():
bus.mcp.IOC_clear()
(year, month, day, dow, hours, minutes, seconds) = ds.read_all()
lcd.display_string("%02d/%02d/20%02d" % (day, month, year), 1)
lcd.display_string("%02d:%02d:%02d" % (hours, minutes, seconds), 2)
Full reference
Based on kplindegaard/smbus2 interface.
See The SMBus Protocol for more information.
- class SMBus(bus=None, force=False, VID=1240, PID=221, devnum=0, clock=100000)
Initialize and open an i2c bus connection.
- Parameters:
bus (int or str) – (for compatibility only, not used) i2c bus number (e.g. 0 or 1) or an absolute file path (e.g. /dev/i2c-42). If not given, a subsequent call to
open()
is required.force (boolean) – (for compatibility only, not used) force using the slave address even when driver is already using it.
VID – Vendor Id (default to
0x04D8
)PID – Product Id (default to
0x00DD
)clock – I2C clock frequency (default to
100kHz
)
- block_process_call(i2c_addr, register, data, force=None)
Executes a SMBus Block Process Call, sending a variable-size data block and receiving another variable-size response
- Parameters:
i2c_addr (int) – i2c address
register (int) – Register to read/write to
data (list) – List of bytes
force (Boolean) –
- Returns:
List of bytes
- Return type:
list
- close()
(For compatibility only, no effects) Close the i2c connection.
- open(bus)
(For compatibility only, no effects) Open a given i2c bus.
- Parameters:
bus (int or str) – i2c bus number (e.g. 0 or 1) or an absolute file path (e.g. ‘/dev/i2c-42’).
- Raises:
TypeError – if type(bus) is not in (int, str)
- process_call(i2c_addr, register, value, force=None)
Executes a SMBus Process Call, sending a 16-bit value and receiving a 16-bit response
- Parameters:
i2c_addr (int) – i2c address
register (int) – Register to read/write to
value (int) – Word value to transmit
force (Boolean) –
- Return type:
int
- read_block_data(i2c_addr, register, force=None)
Read a block of up to 32-bytes from a given register.
- Parameters:
i2c_addr (int) – i2c address
register (int) – Start register
force (Boolean) –
- Returns:
List of bytes
- Return type:
list
- read_byte(i2c_addr, force=None)
Read a single byte from a device.
- Return type:
int
- Parameters:
i2c_addr (int) – i2c address
force (Boolean) –
- Returns:
Read byte value
- read_byte_data(i2c_addr, register, force=None)
Read a single byte from a designated register.
- Parameters:
i2c_addr (int) – i2c address
register (int) – Register to read
force (Boolean) –
- Returns:
Read byte value
- Return type:
int
- read_i2c_block_data(i2c_addr, register, length, force=None)
Read a block of byte data from a given register.
- Parameters:
i2c_addr (int) – i2c address
register (int) – Start register
length (int) – Desired block length
force (Boolean) –
- Returns:
List of bytes
- Return type:
list
- read_word_data(i2c_addr, register, force=None)
Read a single word (2 bytes) from a given register.
- Parameters:
i2c_addr (int) – i2c address
register (int) – Register to read
force (Boolean) –
- Returns:
2-byte word
- Return type:
int
- write_block_data(i2c_addr, register, data, force=None)
Write a block of byte data to a given register.
- Parameters:
i2c_addr (int) – i2c address
register (int) – Start register
data (list) – List of bytes
force (Boolean) –
- Return type:
None
- write_byte(i2c_addr, value, force=None)
Write a single byte to a device.
- Parameters:
i2c_addr (int) – i2c address
value (int) – value to write
force (Boolean) –
- write_byte_data(i2c_addr, register, value, force=None)
Write a byte to a given register.
- Parameters:
i2c_addr (int) – i2c address
register (int) – Register to write to
value (int) – Byte value to transmit
force (Boolean) –
- Return type:
None
- write_i2c_block_data(i2c_addr, register, data, force=None)
Write a block of byte data to a given register.
- Parameters:
i2c_addr (int) – i2c address
register (int) – Start register
data (list) – List of bytes
force (Boolean) –
- Return type:
None
- write_word_data(i2c_addr, register, value, force=None)
Write a single word (2 bytes) to a given register.
- Parameters:
i2c_addr (int) – i2c address
register (int) – Register to write to
value (int) – Word value to transmit
force (Boolean) –
- Return type:
None