Я нашел библиотеку для связи с LTC2983 через шину SPI. Но эта библиотека написана на C ++, и мне нужна эта библиотека для Python. Вот почему я написал библиотеку C ++ в Python. Я не нашел библиотеки в Python для LTC2983.
Библиотека C ++: https://github.com/russeree/rpi_ltc2983
Но когда я хочу прочитать температуру выше Шина SPI с моей библиотекой Python Я не получил ответ от usfuel. Все биты ошибок установлены. Почему установлены все биты ошибок?
Работают функции настройки и инициализации Ltc2983 и термопары. Я проверяю это и контролирую его с помощью таблицы Ltc2983. Я также смотрю на шину SPI с анализатором Logi c. Все из моей библиотеки Python работает, кроме измерения термопары.
- Main
- библиотека функций
- gen library
- определение библиотеки
это моя главная:
import RPi.GPIO as GPIO
import ltc2983_hpp
import def_lib
import spidev
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.OUT)
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 10000
spi.mode = 0b00
d_ideality_f = 0x00101042 #Diode ideality factor of ~ 1.04
chnl_asgn_map = [0]*20 #Intermap of LTC2983 ADC channel mapping
spi_tx = [0]*200 #SPI Tansaction buffer, This gets pushed out to the IC and replace with BCM rx spi pin data
spi_rx = [0]*200 #SPI rx buffer for read data transactions
trans_buff = 0 #Stores a word containing the transaction (32 bit)
temperature = 0
ltc2983_hpp.init_ltc2983(0)
ltc2983_hpp.get_command_status()
chnl_asgn_map[def_lib.CHANNEL_3 - 1] = ltc2983_hpp.setup_thermocouple(def_lib.CHANNEL_3, def_lib.TYPE_K, def_lib.CJ_CHNL_1, def_lib.SNGL, def_lib.OC_CHK_ON, def_lib.TC_100UA)
spi_tx[0] = ltc2983_hpp.write_all_channel_assignments()
for i in range(1): #BSP range(1800)
ltc2983_hpp.all_channel_conversion()
time.sleep(0.2)
temperature = ltc2983_hpp.read_channel_double(def_lib.CHANNEL_3)
if temperature == 9000:
print("The temperature of channel", def_lib.CHANNEL_3, "= ERROR")
else:
print("The temperature of channel", def_lib.CHANNEL_3, temperature)
GPIO.cleanup() #delet the GPIO setup
Моя библиотека функций:
import RPi.GPIO as GPIO
import def_lib
import gen_lib
import spidev
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.OUT)
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 10000
spi.mode = 0b00
chnl_asgn_map = [0]*20
def init_ltc2983(spi_channel):
spi_tx = [0]*4
trans_buff = 0
try:
if (spi_channel > 1) | (spi_channel < 0):
raise 2
else:
spi_channel = spi_channel
except:
print("SPI channel is invalid, 0 and 1 are Supported")
GPIO.output(26, GPIO.LOW)
time.sleep(0.1)
GPIO.output(26, GPIO.HIGH)
time.sleep(0.3)
try:
if spi_channel < 0:
raise 1
except:
print("SPI Setup failed")
trans_buff = gen_lib.gen_transaction(trans_buff, def_lib.WRITE, 0x00F0, 0b00000100)
for k in range(4):
spi_tx[3-k] = (trans_buff >> (8*k)) & 0xff
trans_buff = spi.xfer(spi_tx)
def read_data(address, result, b):
tx_buff = 0 #Stores the complete transaction
byte = b*4
tx = [0]*4 #you could use your results pointer but mem is cheap
for i in range(b):
tx_buff = 0
tx_buff = gen_lib.gen_transaction(tx_buff, def_lib.READ, (address+i), 0x00)
for j in range(4):
tx[3-j] = (tx_buff >> (8*j)) & 0xff
tx_buff = spi.xfer(tx)
if i == 0:
result = tx_buff[3]
return result
def get_command_status():
status_reg = 0
status_reg = read_data(0x0000, status_reg, 1)
print("Command register read and")
if status_reg == 128:
print("LTC2983 is initialized with no channel configuration.")
elif status_reg == 64:
print("LTC2983 is ready for use")
else:
print("was not defined as a valid response")
def setup_thermocouple(channel, tc_type, cj_assignment, snl_ended, oc_chk, oc_curr):
dat_buff = 0x0000
dat_buff |= gen_lib.or_mask_gen(oc_curr, 18)
dat_buff |= gen_lib.or_mask_gen(oc_chk, 20)
dat_buff |= gen_lib.or_mask_gen(snl_ended, 21)
dat_buff |= gen_lib.or_mask_gen(cj_assignment, 22)
dat_buff |= gen_lib.or_mask_gen(tc_type, 27)
chnl_asgn_map[channel - 1] = dat_buff
return chnl_asgn_map[channel - 1]
def setup_diode(channel, snl_ended, three_readings, averaging, exc_current, ideality_f):
dat_buff = 0x0000
dat_buff |= gen_lib.or_mask_gen(ideality_f, 0)
dat_buff |= gen_lib.or_mask_gen(exc_current, 22)
dat_buff |= gen_lib.or_mask_gen(averaging, 24)
dat_buff |= gen_lib.or_mask_gen(three_readings, 25)
dat_buff |= gen_lib.or_mask_gen(snl_ended, 26)
dat_buff |= gen_lib.or_mask_gen(0b11100, 27)
chnl_asgn_map[channel - 1] = dat_buff
def write_all_channel_assignments():
trans_buff = 0 #Buffers the full tranaction byte to be written to the LTC2983
byte_buff = [0]*4 #Used to buffer a word into a byte
byte_null = [0]*4 #Null byte buffer used for transactions
address = 0 #Address Storage
#Generate SPI Transactions
for i in range(20):
print("\nChannel", i+1, "data written.")
#Convert the channel assignment into a 4 byte array for DEBUG read back
for j in range(4):
byte_buff[3-j] = (chnl_asgn_map[i] >> (8*j)) & 0xff
for j in range(4):
for k in range(4):
byte_null[k] = byte_buff[k]
address = (0x200 + i*4 + j)
print("Contents of byte[", j, "] transaction = ", byte_buff[j])
trans_buff = gen_lib.gen_transaction(trans_buff, def_lib.WRITE, address, byte_null[j])
for k in range(4):
byte_null[3-k] = (trans_buff >> (8*k)) & 0xff
byte_null[3] = byte_null[3]
trans_buff = spi.xfer(byte_null)
def all_channel_conversion():
temp = 0
tx_buff = [0]*4
dat_buff = 0
all_mask = 0x000fffff
address = 0x00F4
#GPIO.setup(19, GPIO.IN)
print("\n")
for i in range(4):
dat_buff = ((all_mask >> (24-(8*i))) & 0xff)
temp = gen_lib.gen_transaction(temp, def_lib.WRITE, (address+i), dat_buff)
print("Writing multi channel conversion mask byte", i,":",dat_buff)
for j in range(4):
tx_buff[3-j] = (temp >> (8*j)) & 0xff
temp = spi.xfer(tx_buff)
temp = gen_lib.gen_transaction(temp, def_lib.WRITE, 0x0000, 0x80)
for i in range(4):
tx_buff[3-i] = (temp >> (8*i)) & 0xff
temp = spi.xfer(tx_buff)
print("\nconversion_complete")
def channel_err_decode(channel_number):
status = 0
sensor_type = 0
conversion_status = 0
conversion_result_address = (0x0010 + (4 * (channel_number - 1)))
error_bit_pos = 0
error_string = ["VALID", "ADC OUT OF RANGE", "SENSOR UNDER RANGE", "SENSOR OVER RANGE", "CJ SOFT FAULT", "CJ HARD FAULT", "HARD ADC OUT OF RANGE", "SENSOR HARD FAULT"]
#Readback the channel configuration
conversion_status = read_data(conversion_result_address, conversion_status, 1)
if conversion_status == 255:
print ("\nSensor conversion on channel", channel_number, "status byte returned 0xFF: ALL ERROR BITS AND VALID FLAGGED")
elif conversion_status == 1:
print ("\nConversion on channel", channel_number, "is valid.")
elif conversion_status == 0:
print ("\nNo conversion on channel", channel_number, "occoured.")
else:
print ("\nConversion on channel", channel_number, "contained the following errors.")
for i in range(7):
if((conversion_status >> i) & 0x01) == 1:
print(error_string[i])
def read_channel_double(channel_number):
status = 0
result = 0
temperature = 0
sign = 0
chnl_dat_buff = [0]*4
conversion_result_address = (0x0010 + (4 * (channel_number - 1)))
#Read out the channel information from the SPI bus.
status = read_data(conversion_result_address, chnl_dat_buff[0], 4)
#Now that the channel data buffer is filled check for errors
if (channel_err_decode(channel_number) != 0):
print("Result on channel ", channel_number, " is invalid.")
return 9000
else:
for i in range(4):
print("Raw read value of channel ", channel_number, " byte ", i, " = ", chnl_dat_buff[i])
result = 0;
result = result | (chnl_dat_buff[1]<<16)
result = result | (chnl_dat_buff[2]<<8)
result = result | (chnl_dat_buff[3])
print("Raw bin of result = ", result)
#Convert a 24bit 2s compliment into a 32bit 2s compliment number
if ((chnl_dat_buff[1]&0b10000000)==128):
sign = True
else:
sign = False
#append 1s to the MSB 8 bits
if (sign == 1):
result = result | 0xFF000000
#Compensate for precision
temperature = result / 1024
return temperature
GPIO.cleanup() #delet the GPIO setup
Это библиотека моего поколения:
def gen_transaction(buff, trans_type, address, data):
buff = 0
t_buff = [0]*4
t_buff[3] = trans_type
t_buff[1] = address & 0xff
t_buff[2] = (address >> 8) & 0xff
t_buff[0] = data
for i in range(4):
buff |= t_buff[i] << (i*8)
return buff
def or_mask_gen(value, bit_pos):
return(value << bit_pos)
Моя библиотека определений:
#rpi_ltc2983.gen_transaction(buff,trans_type,address,data)
#rpi_ltc2983.or_mask_gen(value,bit_pos)
# WRITE AND READ COMMANDS
NOP = 0x01
WRITE = 0x02
READ = 0x03
#BASE ADDRESS MAP
CNV_RSLTS = 0x0010 #START: 0x010 -> END: 0x05F [Word]
CHNL_MAP = 0x0200 #START: 0x200 -> END: 0x24F [Word]
#TC SE/DIFF VALS
SNGL = True
DIFF = False
#This is the sesnor type selection for the channel
UNASSIGNED = 0b00000
TYPE_K = 0b00010
TYPE_CUST = 0b01001
#Channel Number to Array Bindings
CHANNEL_1 = 1
CHANNEL_2 = 2
CHANNEL_3 = 3
CHANNEL_4 = 4
CHANNEL_5 = 5
CHANNEL_6 = 6
CHANNEL_7 = 7
CHANNEL_8 = 8
CHANNEL_9 = 9
CHANNEL_10 = 10
CHANNEL_11 = 11
CHANNEL_12 = 12
CHANNEL_13 = 13
CHANNEL_14 = 14
CHANNEL_15 = 15
CHANNEL_16 = 16
CHANNEL_17 = 17
CHANNEL_18 = 18
CHANNEL_19 = 19
CHANNEL_20 = 20
#Input Channel Mapping
#This is the input channels represented in binary form
MULTI_CHNL = 0b10000000
CHNL_1 = 0b10000001
CHNL_2 = 0b10000010
CHNL_3 = 0b10000011
CHNL_4 = 0b10000100
CHNL_5 = 0b10000101
CHNL_6 = 0b10000110
CHNL_7 = 0b10000111
CHNL_8 = 0b10001000
CHNL_9 = 0b10001001
CHNL_10 = 0b10001010
CHNL_11 = 0b10001011
CHNL_12 = 0b10001100
CHNL_13 = 0b10001101
CHNL_14 = 0b10001110
CHNL_15 = 0b10001111
CHNL_16 = 0b10010000
CHNL_17 = 0b10010001
CHNL_18 = 0b10010010
CHNL_19 = 0b10010011
CHNL_20 = 0b10010100
CHNL_SLP = 0b10010111
"""Thermocouple Definitions"""
#TC Cold Junction Mapping
#This is the cold junction channels represented in binary form
NO_CJ = 0b00000
CJ_CHNL_1 = 0b00001
CJ_CHNL_2 = 0b00010
CJ_CHNL_3 = 0b00011
CJ_CHNL_4 = 0b00100
CJ_CHNL_5 = 0b00101
CJ_CHNL_6 = 0b00110
CJ_CHNL_7 = 0b00111
CJ_CHNL_8 = 0b01000
CJ_CHNL_9 = 0b01001
CJ_CHNL_10 = 0b01010
CJ_CHNL_11 = 0b01011
CJ_CHNL_12 = 0b01100
CJ_CHNL_13 = 0b01101
CJ_CHNL_14 = 0b01110
CJ_CHNL_15 = 0b01111
CJ_CHNL_16 = 0b10000
CJ_CHNL_17 = 0b10001
CJ_CHNL_18 = 0b10010
CJ_CHNL_19 = 0b10011
CJ_CHNL_20 = 0b10100
#C Excitation Current ex. EXT, This is the excitation current provided by the LTC2983
#EXT is the external excitation source will be used
TC_EXT_C = 0b00
TC_10UA = 0b00
TC_100UA = 0b01
TC_500UA = 0b10
TC_1000UA = 0b11
#TC SE/DIFF VALS
SNGL = True
DIFF = False
#Over current protection
OC_CHK_ON = True
OC_CHK_OFF = False
"""DIODE CONFIGURATION"""
#2 or 3 readigs, Diode Readings at 2 or 3 different current levels
CONV_3 = True
CONV_2 = False
#Averaging mode enabled *Use this only if diode is stable
D_AVG_ON = True
D_AVG_OFF = False
#Excitation Current Settins
D_10UA = 0b00
D_20UA = 0b01
D_40UA = 0b10
D_80UA = 0b11