Работа AD5272 с Python 3 и smbus2 на Raspberry Pi 3 B+
У меня проблема с работой AD5272 с использованием Python 3 на Raspberry Pi 3 B+. AD5272 - реостат с цифровым управлением и интерфейсом I2C (моя часть имеет сопротивление 20 кОм).
Проблема заключается в следующем:
Сопротивление между клеммами A и W не меняет положение, которое я пытаюсь настроить, и составляет около 10 кОм. (По умолчанию, когда AD5272 включается, устанавливает половину полного сопротивления там). Когда я читаю сопротивление от RDAC - это читает нулевое сопротивление.
Вот мой код:
#!/usr/bin/python3
import smbus2
import time, os
class AD527x ():
# command bits which are dependant on I2C address of device
def __init__ (self, bus=1, address=0x2E, resistance = 20000, positions = 1023, reset = False):
self.bus = smbus2.SMBus(bus)
self.positions = positions
self.address = address
self.resistance = resistance
def write_position (self, position):
# sets the rheostat to certain position
# if wiper position is higher than maximal
if position > self.positions:
position = self.positions
# approximate resistance of rheostat
resistance = self.resistance*position/self.positions
# for AD5274 needs to be shifted for 2 digits left
if self.positions == 256:
position = position << 2
print ("Binary representation of position for RDAC : " + bin (position))
# Writing position is sneding 2 bytes one by one
# MSB Data: 0 0 C3 C2 C1 C0 D9 D8
# For writing command bytes: C3 = 0; C2 = 0; C1 = 0; C0 = 1
# 0 0 0 0 0 1 ? ?
# ? ? - MSB of 10-digit binary representation of wiper position between 0 and 1023
# two first positions : D9_8 = (position & 0b1100000000) >> 8
MSB = (1 << 3) | ((position & 0b1100000000) >> 8)
print ("MSB : " + bin(MSB))
# take last 8 bits
LSB = position & 0b11111111
print ("LSB : " + bin(LSB))
print ("All Bytes : " + bin((MSB << 8) +LSB))
print ("Value : " + str(resistance))
self.bus.write_i2c_block_data(self.address, 0, [MSB, LSB])
self.read_position()
def read_position (self):
# reads current position of rheostat
# prepare the circuit to send data
# MSB Data: 0 0 C3 C2 C1 C0 D9 D8
# For reading command bytes: C3 = 0; C2 = 0; C1 = 1; C0 = 0
# 0 0 0 0 1 0 ? ?
# ? ? - Doen't matter - Just use zeros
# LSB - doesn't matter, just using 0b00000000
MSB = 0b00001000
LSB = 0b00000000
self.bus.write_i2c_block_data(self.address, 0, [MSB, LSB])
#read 2 bytes from RDAC
a = self.bus.read_byte(self.address)
time.sleep (0.005)
b = self.bus.read_byte(self.address)
value = ((a << 8) | b )
print (value)
# take 10 lats bits only
value = value & 0b1111111111
print (value)
def main():
device = AD527x()
device.write_position(1023)
if __name__ == "__main__":
main()
Выход:
Binary representation of position for RDAC : 0b1111111111
MSB : 0b1011
LSB : 0b11111111
All Bytes : 0b101111111111
Value : 20000.0
4096
0
Компьютер: Rapberry Pi 3, модель B +
ОС: Распбиан 9
Версия Python: 3.5.3
Пакет I2C: smbus2
Номер детали: AD5272BRMZ-20
Лист данных: http://www.farnell.com/datasheets/1706490.pdf
Ссылка на продукт: http://www.newark.com/webapp/wcs/stores/servlet/ProductDisplay?catalogId=10001&langId=-1&urlRequestType=Base&partNumber=52R8114&storeId=10194
Что я делаю не так и как это исправить?
Проводка детали была проверена трижды. Чтения из RDAC всегда одинаковы, независимо от значения, которое я пытаюсь записать. Я попробовал обе команды:
self.bus.write_i2c_block_data(self.address, 0, [MSB, LSB])
а также
self.bus.write_byte (self.address, MSB)
self.bus.write_byte (self.address, LSB)
Результат всегда был один и тот же: сопротивление не меняется. Сопротивление проверялось с помощью внешнего омметра.
Пожалуйста помоги!
1 ответ
Я просто ударил эту же проблему. Я еще не рассматривал взаимодействие с Python, но, тем не менее, это может помочь.
В моей схеме I2C AD5272 имеет адрес GND, и у меня есть клемма A, подключенная к VDD (5 В) и W последовательно с резистором 100 к GND.
Сначала я убедился, что устройство работает через драйвер Linux, модули должны быть уже встроены. Как корень:
$ echo ad5272 0x2f > /sys/bus/i2c/devices/i2c-1/new_device
$ dmesg | tail -n 2
[ 711.195428] i2c i2c-1: new_device: Instantiated device ad5272 at 0x2f
[ 711.242537] ad_dpot 1-002f: ad5272 1024-Position Digital Potentiometer registered
$ cat /sys/bus/i2c/devices/1-002f/rdac0
511
$ echo 0 > /sys/bus/i2c/devices/1-002f/rdac0
$ cat /sys/bus/i2c/devices/1-002f/rdac0
0
$ echo 1023 > /sys/bus/i2c/devices/1-002f/rdac0
$ cat /sys/bus/i2c/devices/1-002f/rdac0
1023
Измерение напряжения от W до GND дало ~5 В при 0 и ~2,5 В при 1023.
Затем я повторил с логическим анализатором, подключенным к шине I2C. Команды для записи были:
0x5e 0x1c 0x03 0x5e 0x04 0x00
0x5e 0x1c 0x03 0x5e 0x07 0xff
Надеемся, что это даст нам подсказку, перечитайте разделы в техническом описании на "защита от записи" и "описание управляющего регистра". В моей настройке я хочу использовать только цифровой интерфейс, а не сохраненную память для управления, поэтому я произвел репликацию из пространства пользователя с небольшим изменением:
sudo i2cset 1 0x2f 0x1c 0x02 b
sudo i2cset 1 0x2f 0x04 0x00 b
sudo i2cset 1 0x2f 0x07 0xff b