MCP3428 4 channel not properly reading channels 2,3,4

Using this code:

All I did was change the print statements to python3 and wrapped it in a while 1: statement and added time.sleep(.3) at the top of the while.

Sensors plugged into channel 1 and 2. Thing is acting like its completely ignoring channel 2, 3, 4 and is spitting out whatever value is read on channel 1. Why? I am expecting to be able to read two sensors completely independently.

# Distributed with a free-will license.
# Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
# MCP3428
# This code is designed to work with the MCP3428_I2CADC I2C Mini Module available from ControlEverything.com.
# https://www.controleverything.com/content/Analog-Digital-Converters?sku=MCP3428_I2CADC#tabs-0-product_tabset-2

import smbus2 as smbus
import time

# Get I2C bus
bus = smbus.SMBus(1)

while 1:
    time.sleep(.3)
    # MCP3428 address, 0x68(104)
    # Send configuration command
    #           0x10(16)        Continuous conversion mode, Channel-1, 12-bit Resolution
    bus.write_byte(0x68, 0x10)

    # MCP3428 address, 0x68(104)
    # Read data back from 0x00(0), 2 bytes
    # raw_adc MSB, raw_adc LSB
    data = bus.read_i2c_block_data(0x68, 0x00, 2)

    # Convert the data to 12-bits
    raw_adc = (data[0] & 0x0F) * 256 + data[1]
    if raw_adc > 2047 :
        raw_adc -= 4095

    # Output data to screen
    print ("Digital value of Analog Input on Channel-1: %d" %raw_adc)

    # MCP3428 address, 0x68(104)
    # Send configuration command
    #           0x30(48)        Continuous conversion mode, Channel-2, 12-bit Resolution
    bus.write_byte(0x68, 0x30)

    # MCP3428 address, 0x68(104)
    # Read data back from 0x00(0), 2 bytes
    # raw_adc MSB, raw_adc LSB
    data = bus.read_i2c_block_data(0x68, 0x00, 2)

    # Convert the data to 12-bits
    raw_adc = (data[0] & 0x0F) * 256 + data[1]
    if raw_adc > 2047 :
        raw_adc -= 4095

    # Output data to screen
    print ("Digital value of Analog Input on Channel-2: %d" %raw_adc)

    # MCP3428 address, 0x68(104)
    # Send configuration command
    #           0x50(80)        Continuous conversion mode, Channel-3, 12-bit Resolution
    bus.write_byte(0x68, 0x50)

    # MCP3428 address, 0x68(104)
    # Read data back from 0x00(0), 2 bytes
    # raw_adc MSB, raw_adc LSB
    data = bus.read_i2c_block_data(0x68, 0x00, 2)

    # Convert the data to 12-bits
    raw_adc = (data[0] & 0x0F) * 256 + data[1]
    if raw_adc > 2047 :
        raw_adc -= 4095

    # Output data to screen
    print ("Digital value of Analog Input on Channel-3: %d" %raw_adc)

    # MCP3428 address, 0x68(104)
    # Send configuration command
    #           0x70(112)       Continuous conversion mode, Channel-4, 12-bit Resolution
    bus.write_byte(0x68, 0x70)

    # MCP3428 address, 0x68(104)
    # Read data back from 0x00(0), 2 bytes
    # raw_adc MSB, raw_adc LSB
    data = bus.read_i2c_block_data(0x68, 0x00, 2)

    # Convert the data to 12-bits
    raw_adc = (data[0] & 0x0F) * 256 + data[1]
    if raw_adc > 2047 :
        raw_adc -= 4095

    # Output data to screen
    print ("Digital value of Analog Input on Channel-4: %d" %raw_adc)
Digital value of Analog Input on Channel-1: 494
Digital value of Analog Input on Channel-2: 494
Digital value of Analog Input on Channel-3: 494
Digital value of Analog Input on Channel-4: 494
Digital value of Analog Input on Channel-1: 494
Digital value of Analog Input on Channel-2: 494
Digital value of Analog Input on Channel-3: 494
Digital value of Analog Input on Channel-4: 494
Digital value of Analog Input on Channel-1: 494
Digital value of Analog Input on Channel-2: 494
Digital value of Analog Input on Channel-3: 494
Digital value of Analog Input on Channel-4: 494
Digital value of Analog Input on Channel-1: 494
Digital value of Analog Input on Channel-2: 494
Digital value of Analog Input on Channel-3: 494
Digital value of Analog Input on Channel-4: 494
Digital value of Analog Input on Channel-1: 494
Digital value of Analog Input on Channel-2: 494
Digital value of Analog Input on Channel-3: 494
Digital value of Analog Input on Channel-4: 494

Try adding a short time.sleep between the bus.write and bus.read functions. It’s possible the bus is being quarried before the device responded.

Thanks, but unfortunately I have tried that (after I posted this). Didn’t seem to make a difference.

Am I missing something or does this line need to change based on the channel number I’m reading from. I’m trying to sludge through the datasheet for the MCP3428 but its pretty dense. https://ww1.microchip.com/downloads/en/DeviceDoc/22226a.pdf

 data = bus.read_i2c_block_data(0x68, 0x00, 2)

No, that line simply reads 2 bytes of data from the device at the I2C bus address of 0x68.

The line that requests data from a particular channel is:

bus.write_byte(0x68, 0x10)

That command tells the device you want the input reading for input 1. To read from input 2 the command would be:

bus.write_byte(0x68, 0x30)

Input 3: 50
Input 4: 70

Thanks. Yeah, I thats what I assumed based on the code as the only line that was changing was the bus.write_byte(0x68, 0x10) lines for each channel however that doesn’t seem to be working. I get the above results. It acts like it almost “locks up”. There is no variation.

So for example, if I comment out channel 2,3,4 I’ll get results like.

Digital value of Analog Input on Channel-1: 495
Digital value of Analog Input on Channel-1: 495
Digital value of Analog Input on Channel-1: 495
Digital value of Analog Input on Channel-1: 494
Digital value of Analog Input on Channel-1: 495
Digital value of Analog Input on Channel-1: 495
Digital value of Analog Input on Channel-1: 496
Digital value of Analog Input on Channel-1: 495

When I add channel-2 it does the same as above just a solid set of value that doesn’t have any “noise” in it. Do you know of a good way to validate/troubleshoot why that is the case? Could having to use smbus2 instead of smbus have anything to do with it?

Can you provide a photo of how you are connecting the external signal to the ADC?

Thanks. So I revisited the timing issue you mentioned and it seems you were correct.

I had a delay but whatever I had wasn’t long enough apparently. I added like 100ms delay between all calls and was able to capture the data correctly.

Adding the delay between the write and the read is where it was at just like you said.

It has it in n my head that each channel was storing data for each channel in continuous mode and the bus config was just directing which channel to read from.

However it seems that once you send the config you have to wait for the chip to perform the sample at least once then read (i assumed it was doing it continuously in background).

This seems to be accurate as the sample code is using 12-bit which means it will sample at 4.16ms. If an add a 5ms delay is works. If I make it 3ms delay it doesn’t work.

But now that I think about it, it makes sense.

No matter. the example code doesn’t work as it sits because of this. Might make sense to add at least a note explaining it.

Thanks again for pointing me in right direction.