Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 1268

Python • I2C not working along with SPI

$
0
0
Hi
We have some rather complex python code that uses a pair of MAX 38155 thermocouple amplifiers (SPI), an MCP3424 (I2C) and an MCP23017 (I2C). They are all connected to the right pins on the gpio (I2C devices to gpio2, 3 SPI devices to SPI0, SPI1 with only CS0 enabled for both). When only SPI is on in config.txt the thermocouple amps work perfectly. When we turn I2C on we only get 0 as the output for SPI. We have checked continuity and gpio and there does not seem to be any electrical issues. Anyone have any ideas?
Here is config.txt

Code:

# For more options and information see# http://rptl.io/configtxt# Some settings may impact device functionality. See link above for details# Uncomment some or all of these to enable the optional hardware interfacesdtparam=i2c_arm=off#dtparam=i2s-gpio,bus=0,i2c_gpio_sda=2,i2c_gpio_scl=3 dtparam=spi=on# Enable audio (loads snd_bcm2835)dtparam=audio=on# Additional overlays and parameters are documented# /boot/firmware/overlays/README# Automatically load overlays for detected camerascamera_auto_detect=1# Automatically load overlays for detected DSI displaysdisplay_auto_detect=1# Automatically load initramfs files, if foundauto_initramfs=1# Enable DRM VC4 V3D driverdtoverlay=vc4-kms-v3dmax_framebuffers=2# Don't have the firmware create an initial video= setting in cmdline.txt.# Use the kernel's default instead.disable_fw_kms_setup=1# Run in 64-bit modearm_64bit=1# Disable compensation for displays with overscandisable_overscan=1# Run as fast as firmware / board allowsarm_boost=1[cm4]# Enable host mode on the 2711 built-in XHCI USB controller.# This line should be removed if the legacy DWC2 controller is required# (e.g. for USB device mode) or if USB support is not required.otg_mode=1[all]dtoverlay=spi0-1cs,cs0_pin=8dtoverlay=spi1-1cs,cs0_pin=18
Here is a snippet of our SPI code

Code:

# Thermocouple 1        self.spi_0 = busio.SPI(clock=board.SCK, MISO=board.MISO)        self.cs_0 = digitalio.DigitalInOut(board.D13)        self.tc1 = adafruit_max31855.MAX31855(self.spi_0, self.cs_0)        # Thermocouple 2        self.spi_1 = busio.SPI(clock=board.SCK_1, MISO=board.MISO_1)        self.cs_1 = digitalio.DigitalInOut(board.D5)        self.tc2 = adafruit_max31855.MAX31855(self.spi_1, self.cs_1)
Here is our I2C method

Code:

try:    On_Device = True    import pi_MCP342x    import smbus2 as smbusexcept:    On_Device = Falseimport timeclass Mcp3424:    def __init__(self, i2c_address, i2c_smbus_interface, resolution=14, gain=1):        self.i2c_address = i2c_address        self.adc = pi_MCP342x.MCP342x(i2c_smbus_interface, self.i2c_address, smbus)        self.adc.set_channel(2)        self.adc.set_resolution(resolution)        self.adc.set_gain(gain)        self.adc.write_config()    def adc_resolution_changer(self, gain, resolution):  #Automatically sets adc resolution based on number of bits and test frequency, all values set for half of total ADC SPS        if resolution == "18 bit 3.75 SPS":            resolution = 18        elif resolution == "16 bit 15 SPS":            resolution = 16        elif resolution == "14 bit 60 SPS":            resolution = 14        else:            resolution = 12        if gain == "1x":            gain = 1        elif gain == "2x":            gain = 2        elif gain == "4x":            gain = 4        else:            gain = 8        self.adc.set_resolution(resolution)        self.adc.set_gain(gain)        self.adc.write_config()    def read_SD(self, resistance):        self.adc.set_channel(2, True)        voltage = self.adc.read()        return -voltage/(resistance * 100)    def read_GG(self, resistance):        self.adc.set_channel(1, True)        voltage = self.adc.read()        return -voltage / (resistance * 100)        class GPIO_ex:    def __init__(self, i2c_address, i2c_smbus_interface):        '''        Inputs:        ________________________________________________________________________________________________________________        i2c_address -           (binary/hex/int) I2C address of slave device, on mkII this is 0b00100111        i2c_smbus_interface -   (SMbus object) Runs I2C communication between master and slave        ________________________________________________________________________________________________________________        Stored in self:        ________________________________________________________________________________________________________________        self.I2C -              (SMbus object) Runs I2C communication between master and slave        self.i2c_address -      (binary/hex/int) I2C address of slave device, on mkII this is 0x27        self.byte_a -           (binary/int) Storage for current GPIO configuration for all pins marked A0-7        self.byte_b -           (binary/int) Storage for current GPIO configuration for all pins marked B0-7        self.output_dir_a -     (binary/int) Storage for pin usage direction (input or output, 1 is input) for all pins                                marked A0-7        self.output_dir_b -     (binary/int) Storage for pin usage direction (input or output, 1 is input) for all pins                                marked B0-7        '''        if not 0x20 <= i2c_address <= 0x27:            raise Exception("Invalid I2C address for MCP23017.")        self.I2C = i2c_smbus_interface        self.i2c_address = i2c_address        self.byte_a = [0, 0, 0, 0, 0, 0, 0, 0]        self.byte_b = [0, 0, 0, 0, 0, 0, 0, 0]        self.output_dir_a = [1, 1, 1, 1, 1, 1, 1, 1]        self.output_dir_b = [1, 1, 1, 1, 1, 1, 1, 1]    def set_GPIO(self, pins, is_output=True, is_high=None):        '''        Function to set the state of all expander GPIO pins, including logic level (HIGH/LOW) and pin direction (IN/OUT)        ________________________________________________________________________________________________________________        Inputs:        ________________________________________________________________________________________________________________        pins -              (List of ints, 0-15 no repeats) List of pins to be changed. Any not listed will remain as        they were        is_output -         (None, bool or list of bools) Sets the direction of pins. A list will individually assign                            directions, a bool will assign the same direction for all chosen pins and None will have no                            effect on direction        is_high -           (None, bool or list of bools) Sets logic level of pins (True is HIGH, False is LOW). A list                            will individually assign logic levels, a bool will assign the same logic level for all                            chosen pins and a None will have no effect on logic level        ________________________________________________________________________________________________________________        Outputs:        Nothing pythonic, only hardware        ________________________________________________________________________________________________________________        Note. For logic states a high value is a "1" bit, a low value is a "0" bit. A "1" for output corresponds to a        pin set to be an input, a "0" corresponds to an output pin.        '''        if not isinstance(pins, list) and isinstance(pins, int):            pins = [pins]        elif not isinstance(pins, list) or not all(isinstance(pin, int) for pin in pins):            raise Exception("Invalid form of type " + str(type(pins)) + ".")        if len(pins) != len(set(pins)):            raise TypeError("Pin list contains duplicates")        if not isinstance(is_high, list) and isinstance(is_high, bool):            is_high = [is_high for _ in pins]        elif isinstance(is_high, list) and all(isinstance(state, bool) for state in is_high) and len(is_high) == len(                pins):            pass        elif is_high == None:            pass        else:            raise TypeError(                "Pin logic state(s) are not in correct form. Must be either single bool or bool list with equal length to list of pins.")        if not isinstance(is_output, list) and isinstance(is_output, bool):            is_output = [is_output for _ in pins]        elif isinstance(is_output, list) and all(isinstance(state, bool) for state in is_output) and len(                is_output) == len(pins):            pass        elif is_output == None:            pass        else:            raise TypeError(                "Pin logic state(s) are not in correct form. Must be either single bool or bool list with equal length to list of pins.")        for index, pin in enumerate(pins):            if isinstance(pin, int):                if not 0 <= pin <= 15:                    raise Exception("Invalid pin number for MCP23017. " + str(                        pin) + " is not in the range of 0-15 (0-7 are A0-7, 8-15 are B0-7).")            if 0 <= pin <= 7:  # Handles High/Low and I/O logic on pins A0-A7                if is_high[index]:                    self.byte_a[pin] = 1                elif not is_high[index]:                    self.byte_a[pin] = 0                if is_output[index]:                    self.output_dir_a[pin] = 0                elif not is_output[index]:                    self.output_dir_a[pin] = 1            if 8 <= pin <= 15:  # Handles High/Low and I/O logic on pins B0-B7                if is_high[index]:                    self.byte_b[pin - 8] = 1                elif not is_high[index]:                    self.byte_b[pin - 8] = 0                if is_output[index]:                    self.output_dir_b[pin - 8] = 0                elif not is_output[index]:                    self.output_dir_b[pin - 8] = 1        output_dir_a = self.list_to_bin(self.output_dir_a)        byte_a = self.list_to_bin(self.byte_a)        output_dir_b = self.list_to_bin(self.output_dir_b)        byte_b = self.list_to_bin(self.byte_b)        self.I2C.write_byte_data(self.i2c_address, 0x00, output_dir_a)        self.I2C.write_byte_data(self.i2c_address, 0x01, output_dir_b)        if is_output:            self.I2C.write_byte_data(self.i2c_address, 0x14, byte_a)            self.I2C.write_byte_data(self.i2c_address, 0x15, byte_b)    def list_to_bin(self, digits):  # Converts list to binary integer        return sum(c << i for i, c in enumerate(digits))    def read_GPIO(self, pin):        '''        Reads the logic state of a certain pin        ________________________________________________________________________________________________________________        Inputs:        ________________________________________________________________________________________________________________        pin -               (int) pin between 0-15        ________________________________________________________________________________________________________________        Outputs:        ________________________________________________________________________________________________________________        Pin state as bool, True is HIGH, False is LOW        '''        if 0 <= pin <= 7:            data = self.I2C.read_byte_data(self.i2c_address, 0x12)            return bool((data >> pin) & 1)        else:            pin = pin - 8            data = self.I2C.read_byte_data(self.i2c_address, 0x13)            return bool((data >> pin) & 1)

Statistics: Posted by Jollyjep — Wed Mar 20, 2024 2:37 pm



Viewing all articles
Browse latest Browse all 1268

Trending Articles