python玩转树莓派(六) IIC 及 smbus2
2021-05-10 本文已影响0人
熊爸天下_56c7
一. 开启IIC
树莓派的IIC默认是关闭的, 需要配置开启
1. 方法一. 图形界面
2. 方法二. 终端开启
在终端输入:
sudo raspi-config
3. 查看iic是否启动
在终端输入:
lsmod
可以看到i2c-bcm2708
和 i2c-dev
,证明启动成功
二. 硬件监控及设备识别
1. 安装i2ctool
这个工具用于I2c硬件监控, 设备识别
sudo apt-get install i2c-tools
2. 查询i2c总线
i2cdetect -l
3. 查询i2c设备
i2cdetect -y 1
我试验了AHT10 SHT20 OLED12864(SH1106) 发现SHT20并不能识别❓🤨🤨🤨❓
4. 从i2c设备读出寄存器
sudo i2cdump -y 1 0x38
5. 向i2c设备写寄存器
sudo i2cset -y 1 0x38 0x90 0x55
其中 0x90: 寄存器地址 ,0x55 : 数据
6. 从i2c设备读出特定寄存器
sudo i2cget -y 1 0x38 0x90
三. python IIC库 -- smbus2
https://pypi.org/project/smbus2/
安装smbus2
pip install smbus2
1. 导入模块,实例化
from smbus2 import SMBus
i2c = SMBus(1) # 1 代表 /dev/i2c-1
2. 当前支持的功能
获取i2c功能(I2C_FUNCS)
SMBus数据包错误检查(PEC)支持
read_byte
write_byte
read_byte_data
write_byte_data
read_word_data
write_word_data
read_i2c_block_data
write_i2c_block_data
write_quick
process_call
read_block_data
write_block_data
block_process_call
i2c_rdwr-具有重复启动功能的组合读/写事务
3. open() 打开一个i2c bus
i2c.open(1) # 1 代表 /dev/i2c-1
4. close() 关闭一个i2c bus
i2c.close()
5.read_byte //从设备读取一个字节
read_byte(i2c_addr, force=None)
参数:
- i2c_addr (整形) – i2c 地址
返回值:
- 读取的字节
6.write_byte //向设备写入一个字节
write_byte(i2c_addr, value, force=None)
参数:
- i2c_addr (整形) – i2c 地址
- value(整形) -要写入的值
返回值:
- 无
7.read_byte_data //从指定的寄存器中读取一个字节
read_byte_data(i2c_addr, register, force=None)
参数:
- i2c_addr (整形) – i2c 地址
- register(整形)–读取的寄存器
返回值:
- 读取的字节
8.write_byte_data //向指定的寄存器中写入一个字节
write_byte_data(i2c_addr, register, value, force=None)
参数:
- i2c_addr (整形) – i2c 地址
- register(整形)–读取的寄存器
- value(整形) -要写入的值
返回值:
- 无
9.read_i2c_block_data //从给定的寄存器中读取字节数据块
read_i2c_block_data(i2c_addr, register, length, force=None)
参数:
- i2c_addr (整形) – i2c 地址
- register(整形)–开始寄存器
- length(整形)–所需的块长度
返回值:
- 字节组成的列表
10.write_i2c_block_data //将字节数据块写入给定寄存器
write_i2c_block_data(i2c_addr, register, data, force=None)
参数:
- i2c_addr (整形) – i2c 地址
- register(整形)–开始寄存器
- data(整形)–字节组成的列表
返回值:
- 无
11. read_word_data //从给定的寄存器中读取一个字(2个字节)
read_byte_data(i2c_addr, register, force=None)
参数:
- i2c_addr (整形) – i2c 地址
- register(整形)–开始寄存器
返回值:
- 整形
12. write_word_data //将一个字(2个字节)写入给定的寄存器
write_word_data(i2c_addr, register, value, force=None)
参数:
- i2c_addr (整形) – i2c 地址
- register(整形)–开始寄存器
- value(整形) -要写入的字
返回值:
- 无
四. 举例: 使用smbus2读写AHT10温湿度传感器
AHT10的基本信息:
iic从地址: 0x38
写命令(写地址): 0x70
读命令(读地址): 0x71
初始化方法: 写命令 0xE1,0x08,0x00
复位方法: 写命令 0xBA
读状态和测量结果(返回1字节状态+20比特湿度+20比特温度,共6字节)
import time
AHT10_ADDRESS = 0x38 # AHT10 i2c地址
AHT_TEMPERATURE_CONST = 200 #温度常量
AHT_TEMPERATURE_OFFSET = 50 #温度偏移
CMD_INITIALIZE = [0xE1, 0x08, 0x00] #初始化命令
CMD_RESET = 0xBA #复位命令
CMD_MEASURE = [0xAC, 0x33, 0x00] #测量命令
class AHT10:
def __init__(self, i2c):
if i2c is None:
raise ValueError('I2C object required.')
self.i2c = i2c
self.address = AHT10_ADDRESS
self.aht10_init()
self.readings_raw = []
self.results_parsed = [0, 0]
# 初始化AHT10
def aht10_init(self):
self.aht10_reset()
self.i2c.write_i2c_block_data(self.address,0x70,CMD_INITIALIZE)
# 复位
def aht10_reset(self):
self.i2c.write_byte_data(self.address,0x70,CMD_RESET)
time.sleep(0.1)
# 读数据
def read_raw(self):
self.i2c.write_i2c_block_data(self.address,0x70, CMD_MEASURE)
time.sleep(0.075)
self.readings_raw = self.i2c.read_i2c_block_data(AHT10_ADDRESS,0x71,6)
self.results_parsed[0] = self.readings_raw[1] << 12 | self.readings_raw[2] << 4 | self.readings_raw[3] >> 4
self.results_parsed[1] = (self.readings_raw[3] & 0x0F) << 16 | self.readings_raw[4] << 8 | self.readings_raw[5]
# 湿度
@property
def humidity(self):
self.read_raw()
return (self.results_parsed[0] / 0x100000) * 100
# 温度
@property
def temperature(self):
self.read_raw()
return (self.results_parsed[1] / 0x100000) * AHT_TEMPERATURE_CONST - AHT_TEMPERATURE_OFFSET
#打印方法
def print(self):
print("Temperature: " + str(self.temperature) + "C"+ ", Humidity: " + str(self.humidity))
if __name__ =='__main__':
import smbus2
i2c = smbus2.SMBus(1)
aht10 = AHT10(i2c)
while True:
aht10.print()
time.sleep(2)