Почему все биты ошибок устанавливаются, когда я хочу прочитать термопару с LTC2983 - PullRequest
0 голосов
/ 04 марта 2020

Я нашел библиотеку для связи с LTC2983 через шину SPI. Но эта библиотека написана на C ++, и мне нужна эта библиотека для Python. Вот почему я написал библиотеку C ++ в Python. Я не нашел библиотеки в Python для LTC2983.

Библиотека C ++: https://github.com/russeree/rpi_ltc2983

Но когда я хочу прочитать температуру выше Шина SPI с моей библиотекой Python Я не получил ответ от usfuel. Все биты ошибок установлены. Почему установлены все биты ошибок?

Работают функции настройки и инициализации Ltc2983 и термопары. Я проверяю это и контролирую его с помощью таблицы Ltc2983. Я также смотрю на шину SPI с анализатором Logi c. Все из моей библиотеки Python работает, кроме измерения термопары.

  1. Main
  2. библиотека функций
  3. gen library
  4. определение библиотеки

это моя главная:

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 
...