Jakobs
Jakobs

Reputation: 1

Convert temperature from 3 byte two's complement

I'm trying to read internal temperature of an ADC (ADS1235 from Texas Instrument) using the Raspberry Pi Pico running MicroPython. SPI communication between Raspberry Pi Pico and ADC works (I used an oscilloscope to check). 3 data bytes received form the ADC I have to turn into a number:

ADC response to Read Data command

The data is in two's complement, MSB first. I tried to go from a 24-bit two's complement binary string to a negative or positive number. A positive number calculation works, but for a negative number (where most significant bit is 1) it doesn't. Is there some function for the conversion? Code of converter function where I simulate ADC sent 3 bytes in the order [0x81, 0x00, 0x00]:

import string

def twos_comp_to_decimal(adcreading):
    """compute the int value of 2's complement 24-bit number"""
    """https://www.exploringbinary.com/twos-complement-converter/ look at "implementation" section"""
    """https://note.nkmk.me/en/python-bit-operation/#:~:text=Bitwise%20operations%20in%20Python%20%28AND%2C%20OR%2C%2
    0XOR%2C%20NOT%2C,NOT%2C%20invert%3A%20~%206%20Bit%20shifts%3A%20%3C%3C%2C%20%3E%3E"""

    signbit = False  # Assume adc-reading is positive from the beginning

    if adcreading >= 0b100000000000000000000000:
        signbit = True
        print("negative signbit")

    if signbit:
        print("inv string")
        negativval = bin(~adcreading & 0b011111111111111111111111)
        negativval = int(negativval)
        negativval += 0b000000000000000000000001

        negativval *= -1
        return negativval

    return adcreading

if __name__ == '__main__':
    # tempdata = [0x80, 0xFF, 0x80]
    tempdata = [0x81, 0x00, 0x00]

    print("Slicing 3 databytes into one 24-bit number")
    adc24bit = int.from_bytes(bytearray(tempdata), "big")
    print(adc24bit)
    print(hex(adc24bit))
    print(bin(adc24bit))

    print(twos_comp_to_decimal(adc24bit))
    # print("Integer value: {}".format(adc24bit))

    #temperatureC = ((adc24bit - 122.400) / 420) + 25
    #print("Temp in celcius: {}".format(temperatureC))

output given negative input

Upvotes: 0

Views: 207

Answers (1)

Pedro Rodrigues
Pedro Rodrigues

Reputation: 36

I wrote this function to do the conversion from 24 bit written in two's complement to decimal, the number you provided as an example turned out to be -8323072, I checked this value here: https://www.exploringbinary.com/twos-complement-converter/.

Here is the code I wrote:

# example data
data = [0x81, 0x00, 0x00]
data_bin = bytearray(data)

def decimal_from_two_comp(bytearr):

    string = ''
    for byte in bytearr:
        string = string + f'{byte:08b}'
    # string with the the 24 bits
    print(string)

    # conversion from two complement to decimal
    decimal = -int(string[0]) * 2**23

    for i,num in enumerate(string[1:]):
        num = int(num)

        decimal += num * 2**(23 - (i + 1))

    return decimal

You can check on the wikipedia page for Two's Complement under the section Converting from two's complement representation that the algorithm I provided results in the formula they present in that section.

Upvotes: 0

Related Questions