如何使用 twisted 的 SerialPort/Protocol 类 定义 i2c 地址
How to define an i2c address using twisted's SerialPort/Protocol classes
我正在尝试使用 twisted 访问 I2C 设备。两个设备都在同一个 I2C 端口 /dev/i2c-1
上并且具有不同的地址 (0x68,0x69)。我的问题是我很难理解我应该在我的代码逻辑中的什么地方为我的设备指定 I2C 地址。
我有一个现有的工作脚本,它使用扭曲的串行端口、协议和工厂从不同的传感器获取输入。下面的代码缺少的是一种指示从哪个 I2C 地址读取传入数据的方法。我在 GitHub 上发现 a I2cProtocol extension 到 twisted 的协议 class 并尝试根据我的目的调整它,但是在接收到的数据上访问该扩展中的 i2c 地址。如果我在同一个 I2C 端口上有两个设备,我不希望它起作用。
为简单起见,这是我的脚本的简化版本,显示了与 I2C 设备有关的部分:
from twisted.internet import reactor
from twisted.internet.serialport import SerialPort
from twisted.internet.protocol import Protocol
class IMU_Protocol(Protocol):
#Class to log IMU
def constants(self, sensor, I2C_ADDR):
self.sensor = sensor
self.I2C_ADDR = I2C_ADDR
def dataReceived(self, data):
print 'dataReceivedIMU called', time.time()
#how do I specify which address to take the data from?
i2c_address, value = data
imu_numbers = (1,2)
i2c_addresses = (0x68,0x69)
sen_log_instances = {} #dictionary of logging instances
for imu_no,imu_addr in zip(imu_numbers,i2c_addresses):
sen_log_instances['IMU_'+imu_no]= IMU_Protocol()
sen_log_instances['IMU_'+imu_no].constants(imu_no,imu_addr)
SerialPort(sen_log_instances['IMU_'+imu_no],'/dev/i2c-1', reactor, baudrate='115200')
sensor_numbers += ('IMU_'+imu_no,)
fact = EchoClientFactory(sen_log_instances,sensor_numbers, field_name)
reactor.run()
我认为通过模拟 SerialPort 或其他开箱即用的扭曲模块中的机制,在扭曲上下文中实现 I2C 支持并不容易。
触发 dataReceived 的关键步骤是让 reactor 知道那里有一个需要监视的 I2C 设备只要一些数据准备就绪,它就应该从那里读取数据并传送给协议。
reactor 作为高级应用程序的一部分对串行或 I2C 等低级内容一无所知,但它对如何操作 FileDescriptor 了解很多是 SerialPort 的工作方式。所以,如果你确实希望你的 I2C 在扭曲中工作,你必须做类似的事情。
- 找到一个Python可以以文件描述符的方式操作I2C的库(不幸的是smbus2不能)
- 子类twisted.internet.abstract.FileDescriptor,重写fileno()、doRead()、doWrite()等方法
- 在初始化时为每个 I2C 地址创建一个实例
您上面提到的 I2C 协议扩展代码对您没有太大帮助,因为它基于非常旧的 Twisted 版本,其中仍在使用 SerialPortEndpoint。最新版本的 Twisted 支持有限类型的端点,因此您必须想出自己的端点。
我正在尝试使用 twisted 访问 I2C 设备。两个设备都在同一个 I2C 端口 /dev/i2c-1
上并且具有不同的地址 (0x68,0x69)。我的问题是我很难理解我应该在我的代码逻辑中的什么地方为我的设备指定 I2C 地址。
我有一个现有的工作脚本,它使用扭曲的串行端口、协议和工厂从不同的传感器获取输入。下面的代码缺少的是一种指示从哪个 I2C 地址读取传入数据的方法。我在 GitHub 上发现 a I2cProtocol extension 到 twisted 的协议 class 并尝试根据我的目的调整它,但是在接收到的数据上访问该扩展中的 i2c 地址。如果我在同一个 I2C 端口上有两个设备,我不希望它起作用。
为简单起见,这是我的脚本的简化版本,显示了与 I2C 设备有关的部分:
from twisted.internet import reactor
from twisted.internet.serialport import SerialPort
from twisted.internet.protocol import Protocol
class IMU_Protocol(Protocol):
#Class to log IMU
def constants(self, sensor, I2C_ADDR):
self.sensor = sensor
self.I2C_ADDR = I2C_ADDR
def dataReceived(self, data):
print 'dataReceivedIMU called', time.time()
#how do I specify which address to take the data from?
i2c_address, value = data
imu_numbers = (1,2)
i2c_addresses = (0x68,0x69)
sen_log_instances = {} #dictionary of logging instances
for imu_no,imu_addr in zip(imu_numbers,i2c_addresses):
sen_log_instances['IMU_'+imu_no]= IMU_Protocol()
sen_log_instances['IMU_'+imu_no].constants(imu_no,imu_addr)
SerialPort(sen_log_instances['IMU_'+imu_no],'/dev/i2c-1', reactor, baudrate='115200')
sensor_numbers += ('IMU_'+imu_no,)
fact = EchoClientFactory(sen_log_instances,sensor_numbers, field_name)
reactor.run()
我认为通过模拟 SerialPort 或其他开箱即用的扭曲模块中的机制,在扭曲上下文中实现 I2C 支持并不容易。
触发 dataReceived 的关键步骤是让 reactor 知道那里有一个需要监视的 I2C 设备只要一些数据准备就绪,它就应该从那里读取数据并传送给协议。
reactor 作为高级应用程序的一部分对串行或 I2C 等低级内容一无所知,但它对如何操作 FileDescriptor 了解很多是 SerialPort 的工作方式。所以,如果你确实希望你的 I2C 在扭曲中工作,你必须做类似的事情。
- 找到一个Python可以以文件描述符的方式操作I2C的库(不幸的是smbus2不能)
- 子类twisted.internet.abstract.FileDescriptor,重写fileno()、doRead()、doWrite()等方法
- 在初始化时为每个 I2C 地址创建一个实例
您上面提到的 I2C 协议扩展代码对您没有太大帮助,因为它基于非常旧的 Twisted 版本,其中仍在使用 SerialPortEndpoint。最新版本的 Twisted 支持有限类型的端点,因此您必须想出自己的端点。