Использование обоих SPI Rasberry с двумя разными RTD - PullRequest
0 голосов
/ 05 мая 2018

Я использую следующий код, чтобы получить температуру PT100 (3-проводной) и PT1000 (2-проводной) одновременно на моей малине. В соответствии с https://cdn -learn.adafruit.com / downloads / pdf / adafruit-max31865-rtd-pt100-amplifier.pdf моя схема подключения правильная.

from Max31865 import Max31865

maxGarraum = Max31865()
maxGarraum.initPt100_3WireSensor(26, True)
maxFleisch = Max31865()
maxFleisch.initPt1000_2WireSensor(24, True)

while True:
    maxGarraum.getCurrentTemp()
    time.sleep(1)

Мой Max31865.py выглядит следующим образом:

import time, math
import RPi.GPIO as GPIO
# import numpy


class Max31865():

    def initPt1000_2WireSensor(self, iCsPin):
        self.csPin = iCsPin

        # Fleischsensor Pt1000 (2-wire)
        self.registerCode = 0xA2
        self.setupGPIO()

    def initPt100_3WireSensor(self, iCsPin):
        self.csPin = iCsPin

        # Garraumsensor Pt100 (3-wire)
        self.registerCode = 0xB2
        self.setupGPIO()

    def setupGPIO(self):
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(self.csPin, GPIO.OUT)
        GPIO.setup(self.misoPin, GPIO.IN)
        GPIO.setup(self.mosiPin, GPIO.OUT)
        GPIO.setup(self.clkPin, GPIO.OUT)

        GPIO.output(self.csPin, GPIO.HIGH)
        GPIO.output(self.clkPin, GPIO.LOW)
        GPIO.output(self.mosiPin, GPIO.LOW)

    def getCurrentTemp(self):is

        # b10000000 = 0x80
        # 0x8x to specify 'write register value'
        # 0xx0 to specify 'configuration register'
        #
        # 0b10110010 = 0xB2
        # Config Register - https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf
        # ---------------
        # bit 7: Vbias -> 1 (ON)
        # bit 6: Conversion Mode -> 0 (MANUAL)
        # bit 5: 1-shot ->1 (ON)
        # bit 4: 3-wire select -> 1 (3 wire config) (0 for 2-/4-wire)
        # bit 3-2: fault detection cycle -> 0 (none)
        # bit 1: fault status clear -> 1 (clear any fault)
        # bit 0: 50/60 Hz filter select -> 0 (60Hz)
        #
        # 0b11010010 or 0xD2 for continuous auto conversion 
        # at 60Hz (faster conversion)

        # one shot
        self.writeRegister(0, self.registerCode)

        # conversion time is less than 100ms
        time.sleep(.1)  # give it 100ms for conversion

        # read all registers
        out = self.readRegisters(0, 8)

        conf_reg = out[0]
        #print("Config register byte: %x" % conf_reg)

        [rtd_msb, rtd_lsb] = [out[1], out[2]]
        rtd_ADC_Code = ((rtd_msb << 8) | rtd_lsb) >> 1
        temp = self.calcTemperature(rtd_ADC_Code)

        """
        # High fault threshold
        [hft_msb, hft_lsb] = [out[3], out[4]]
        hft = ((hft_msb << 8) | hft_lsb) >> 1

        # Low fault threshold
        [lft_msb, lft_lsb] = [out[5], out[6]]
        lft = ((lft_msb << 8) | lft_lsb) >> 1
        print ("High fault threshold: ", hft , " --- Low fault threshold: " , lft)
        """

        status = out[7]

        # 10 Mohm resistor is on breakout board to help
        # detect cable faults
        # bit 7: RTD High Threshold / cable fault open 
        # bit 6: RTD Low Threshold / cable fault short
        # bit 5: REFIN- > 0.85 x VBias -> must be requested
        # bit 4: REFIN- < 0.85 x VBias (FORCE- open) -> must be requested
        # bit 3: RTDIN- < 0.85 x VBias (FORCE- open) -> must be requested
        # bit 2: Overvoltage / undervoltage fault
        # bits 1,0 don't care    
        # print "Status byte: %x" % status

        if ((status & 0x80) == 1):
            raise FaultError("High threshold limit (Cable fault/open)")
        if ((status & 0x40) == 1):
            raise FaultError("Low threshold limit (Cable fault/short)")
        if ((status & 0x04) == 1):
            raise FaultError("Overvoltage or Undervoltage Error")

        return temp


    def writeRegister(self, regNum, dataByte):
        GPIO.output(self.csPin, GPIO.LOW)

        # 0x8x to specify 'write register value'
        addressByte = 0x80 | regNum;

        # first byte is address byte
        #print("Cs-Pin: ", self.csPin, "Addresse: ", addressByte)
        self.sendByte(addressByte)
        # the rest are data bytes
        self.sendByte(dataByte)

        GPIO.output(self.csPin, GPIO.HIGH)

    def readRegisters(self, regNumStart, numRegisters):
        out = []
        GPIO.output(self.csPin, GPIO.LOW)

        # 0x to specify 'read register value'
        self.sendByte(regNumStart)

        for byte in range(numRegisters):    
            data = self.recvByte()
            out.append(data)

        GPIO.output(self.csPin, GPIO.HIGH)
        return out

    def sendByte(self, byte):
        for bit in range(8):
            GPIO.output(self.clkPin, GPIO.HIGH)
            if (byte & 0x80):
                GPIO.output(self.mosiPin, GPIO.HIGH)
            else:
                GPIO.output(self.mosiPin, GPIO.LOW)
            byte <<= 1
            GPIO.output(self.clkPin, GPIO.LOW)

    def recvByte(self):
        byte = 0x00
        for bit in range(8):
            GPIO.output(self.clkPin, GPIO.HIGH)
            byte <<= 1
            if GPIO.input(self.misoPin):
                byte |= 0x1
            GPIO.output(self.clkPin, GPIO.LOW)
        return byte    

    def calcTemperature(self, RTD_ADC_Code):
        global temp

        R_REF = 0.0  # Reference Resistor
        Res0 = 0.0;  # Resistance at 0 degC for 400ohm R_Ref
        a = 0.0
        b = 0.0
        c = 0.0

        if (self.registerCode == 0xA2):
            ############# PT1000 #############
            R_REF = 4300.0  # Reference Resistor
            Res0 = 1000.0;  # Resistance at 0 degC for 430ohm R_Ref
            a = .00381
            b = -.000000602
            # c = -4.18301e-12 # for -200 <= T <= 0 (degC)
            c = -0.000000000006
            # c = 0 # for 0 <= T <= 850 (degC)
        else:
            ############# PT100 #############
            R_REF = 430.0  # Reference Resistor
            Res0 = 100.0;  # Resistance at 0 degC for 430ohm R_Ref
            a = .00390830
            b = -.000000577500
            # c = -4.18301e-12 # for -200 <= T <= 0 (degC)
            c = -0.00000000000418301
            # c = 0 # for 0 <= T <= 850 (degC)

        Res_RTD = (RTD_ADC_Code * R_REF) / 32768.0  # PT1000 Resistance

        #print("CS-Pin: " , self.csPin, " --- ADC-Value: ", RTD_ADC_Code , " --- Resistance: ", round(Res_RTD, 2) , " Ohms")

        # Callendar-Van Dusen equation
        # Res_RTD = Res0 * (1 + a*T + b*T**2 + c*(T-100)*T**3)
        # Res_RTD = Res0 + a*Res0*T + b*Res0*T**2 # c = 0
        # (c*Res0)T**4 - (c*Res0)*100*T**3  
        # + (b*Res0)*T**2 + (a*Res0)*T + (Res0 - Res_RTD) = 0
        #
        # quadratic formula:
        # for 0 <= T <= 850 (degC)
        temp = -(a * Res0) + math.sqrt(a * a * Res0 * Res0 - 4 * (b * Res0) * (Res0 - Res_RTD))
        temp = round(temp / (2 * (b * Res0)), 2)

        # removing numpy.roots will greatly speed things up
        # temp_C_numpy = numpy.roots([c*Res0, -c*Res0*100, b*Res0, a*Res0, (Res0 - Res_RTD)])
        # temp_C_numpy = abs(temp_C_numpy[-1])


        # print "Solving Full Callendar-Van Dusen using numpy: %f" %  temp_C_numpy
        if (temp < 0):  # use straight line approximation if less than 0
            # Can also use python lib numpy to solve cubic
            # Should never get here in this application
            temp = (RTD_ADC_Code / 32) - 256


print ("CSPin " , self.csPin, " - ADC: ", RTD_ADC_Code , " - Resistance: ", round(Res_RTD, 2) , " Ohms - Temp: " , temp)
        return temp

    ##############################################################################################################################
    #                                                         Programmstart                                                       #
    ###############################################################################################################################
    csPin = 0
    misoPin = 21
    mosiPin = 19
    clkPin = 23
    registerCode = 0

    # BOARD:21,19,23
    # BCM: 9,10,11


class FaultError(Exception):
    pass

Проблема в том, что я не получаю данные для PT100-rtd - только для PT1000. Проводка с моей малиной должна быть правильной, потому что я также адаптировал свой код, чтобы проверить проводку с двумя PT1000-rtd, и она работает.

Я думаю, что моя проблема где-то в "getCurrentTemp (self)". Может быть, в readRegister (..) и writeRegister (..) с "regNum" и "regNumStart".

Есть идеи?

1 Ответ

0 голосов
/ 05 мая 2018

Похоже, вы пытаетесь использовать код circuitPython.

Посмотрите на это местоположение для получения последней версии этого кода. Следуйте инструкциям и убедитесь, что у вас есть все необходимое зависимости встретились на вашей платформе.

Посмотрите здесь для их простого примера того, как тестировать.

Удачи!

...