How to convert Github C code into Python script to talk to RTD Click board over Serial Peripheral Interface (SPI).

Thread Starter

Riskinit

Joined Jan 28, 2022
65
Good morning,

I am trying to convert this Github C code: main.c, rtd.c, rtd.h, with functions referenced in the mikroSDK Reference Manual. Here is the datasheet for the RTD Click board. I want to run the converted Python script from a raspberry pi. For the time being you will have to take it on faith that I have wired everything correctly because I truly believe my root problem lies in the code conversion.

The problem is I don't know what message to send to the RTD Click board and how to read the response given. In particular, the rdt.c code has this code below.

Code:
void rtd_generic_transfer
(
    rtd_t *ctx,
    uint8_t *wr_buf,
    uint16_t wr_len,
    uint8_t *rd_buf,
    uint16_t rd_len
)
{
    spi_master_select_device( ctx->chip_select );
    spi_master_write_then_read( &ctx->spi, wr_buf, wr_len, rd_buf, rd_len );
    spi_master_deselect_device( ctx->chip_select );  
}

void rtd_write_register ( rtd_t *ctx, uint8_t reg_address, uint8_t write_data )
{
    uint8_t tmp[ 2 ];

    reg_address |= 0x80;
   
    tmp[ 0 ] = reg_address;
    tmp[ 1 ] = write_data;

    spi_master_select_device( ctx->chip_select );
    spi_master_write( &ctx->spi, tmp, 2 );
    spi_master_deselect_device( ctx->chip_select );   
}

uint8_t rtd_read_register ( rtd_t *ctx, uint8_t reg_address )
{
    uint8_t tmp;
    uint8_t rx_data[ 2 ];

    rtd_generic_transfer( ctx, &reg_address, 1, rx_data, 1 );

    tmp = rx_data[ 0 ];

    return tmp;
}

uint16_t rtd_read_temperature ( rtd_t *ctx )
{
    uint16_t return_value;

    return_value = rtd_read_register( ctx, 0x01 );
    return_value <<= 8;
    return_value |= rtd_read_register( ctx, 0x02 );

    return return_value;
}
I have created the following python code that [un]successfully runs on the hardware. That is, it runs but doesn't give me the answer I want. I referenced the python code from Sparkfun tutorial.

Code:
import RPi.GPIO as GPIO
import time
import spidev

spi_ch = 0

#enable SPI
spi = spidev.SpiDev(0, spi_ch)
spi.max_speed_hz = 100000

def read_adc(adc_ch):
    msg = 0xb00
    msg = [msg, 0xb00000000]
    reply = spi.xfer2(msg)

    adc = 0
    for n in reply:
        adc = (adc << 8) + n
    adc = adc >> 1

    voltage = adc * 1.175
    return voltage

adc = read_adc(0)

print('ADC read: ' + str(adc))

spi.close()
GPIO.cleanup()
I think I could solve my problem if I knew how to convert this line into Python.

Code:
return_vale = rtd_read_register(ctx, 0x01);
ctx is a typedef struct referencing the connection to the Click Board while 0x01 is a register. That line calls this...

Code:
rtd_generic_transfer(ctx, &reg_address, 1, rx_data, 1);
Which writes &reg_address of length 1 to the RTD Click board who then responds with rx_data of length 1. However, rx_data is of length 2 which is why the call rtd_read_register 2x but shift the data 1x.

How do I convert that last line into something python function xfer2(msg) will understand?

Thank you for any advice.
 
Last edited:

Thread Starter

Riskinit

Joined Jan 28, 2022
65
The RTD Click Board is based on the MAX31865 circuit. On page 13 is the reference to various registers. It looks like the first read is to register 0x01 and the second read is to register 0x02. I am still not sure how to read this in python.
 

Thread Starter

Riskinit

Joined Jan 28, 2022
65
This is the bit code I came up with... but I am getting bad results from the chip.

Code:
import RPi.GPIO as GPIO
import time
import sys

CLK = 11
MISO = 9
MOSI = 10
CS = 8
DRDY = 22

def setupSpiPins(clkPin, misoPin, mosiPin, csPin, drdyPin):
    GPIO.setup(clkPin, GPIO.OUT)
    GPIO.setup(misoPin, GPIO.IN)
    GPIO.setup(mosiPin, GPIO.OUT)
    GPIO.setup(csPin, GPIO.OUT)
    GPIO.setup(drdyPin, GPIO.IN)

def readAdc(channel, clkPin, misoPin, mosiPin, csPin, drdyPin):
    GPIO.output(csPin, GPIO.HIGH)

    print(GPIO.input(drdyPin))

    GPIO.output(csPin, GPIO.LOW)
   
    #read first 8 bits
    read_command = [0, 0, 0, 0, 0, 0, 0, 1]
    sendBits(read_command, 8, clkPin, mosiPin)
    adcValue1 = recvBits(8, clkPin, misoPin)

    #read second 8 bits
    read_command = [0, 0, 0, 0, 0, 0, 1, 0]
    sendBits(read_command, 8, clkPin, mosiPin)
    adcValue2 = recvBits(8, clkPin, misoPin)

    print(adcValue1)
    print(adcValue2)

    GPIO.output(csPin, GPIO.HIGH)

    return 0

def sendBits(data, numBits, clkPin, mosiPin):
    for bit in range(numBits):
        GPIO.output(clkPin, GPIO.HIGH)

        if data[bit] == 1:
            GPIO.output(mosiPin, GPIO.HIGH)
        else:
            GPIO.output(mosiPin, GPIO.LOW)

        GPIO.output(clkPin, GPIO.LOW)

def recvBits(numBits, clkPin, misoPin):
    retVal = []

    for bit in range(numBits):
        GPIO.output(clkPin, GPIO.HIGH)

        if GPIO.input(misoPin):
            retBit = 1
        else:
            retBit = 0

        retVal.append(retBit)

        GPIO.output(clkPin, GPIO.LOW)

    return retVal

try:
    GPIO.setmode(GPIO.BCM)
    setupSpiPins(CLK, MISO, MOSI, CS, DRDY)

    while True:
        val = readAdc(0, CLK, MISO, MOSI, CS, DRDY)
        print('ADC Result: ' + str(val))
        time.sleep(5)

except KeyboardInterrupt:
    GPIO.cleanup()
    sys.exit(0)
So I am sending bits [0, 0, 0, 0, 0, 0, 0, 1], and [0, 0, 0, 0, 0, 0, 1, 0] and receiving arrays [0, 0, 0, 0, 0, 0, 0, 0] and [1, 1, 1, 1, 1, 1, 1, 1].

This suggests I am missing something basic in my logic. Thanks in advance for any guidance.
 
Top