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()
Warning
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).
The EasyMCP2221.Device constructor will try to prevent conflicts by caching and returning
the same Object if the same initialization parameters are given, instead of two different objects.
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=1, force=False, VID=1240, PID=221, usbserial=None, clock=100000, mcp=None)
Initialize and open an I2C bus connection. See
EasyMCP2221.Deviceinitialization for details.- Parameters:
bus (int, optional) – Device index starting by 1. Default is to use the first device (index 1).
force (bool, optional) – For compatibility only, not used.
VID (int, optional) – Vendor Id (default is
0x04D8)PID (int, optional) – Product Id (default is
0x00DD)usbserial (str, optional) – Device’s USB serial ID to open.
clock (int, optional) – I2C clock frequency (default to
100kHz).mcp (EasyMCP2221 object, optional) – An already initialized
EasyMCP2221.Deviceobject to use.
- Returns:
SMBus object.
Example
from EasyMCP2221 import SMBus bus = SMBus()
or
from EasyMCP2221 import smbus bus = smbus.SMBus()
- 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