This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] ADS122C04:ADC 读数光电二极管恒定输出。 使用 I2C.Review 电路和代码来连接 ADC 与 Raspberry PI 4。

Guru**** 2387080 points
Other Parts Discussed in Thread: ADS122C04
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1357329/ads122c04-adc-reading-photodiode-constant-output-interacing-adc-with-raspberry-pi-4-using-i2c-review-circuit-and-code

器件型号:ADS122C04

HII、

我尝试使用具有 i2c 的 Raspberry PI4的 ADS122C04读取光电二极管值、但随着输入的变化(光电二极管值)、我将获得恒定输出。

如果我正在使用以下电路、请更正我所用的电路有任何变化。

下面是我正在使用的 ADS122C04的库  

import RPi.GPIO as GPIO
from time import sleep
from smbus2 import SMBus, i2c_msg

class ADS122C04:
    CMD_RESET               = 0x06
    CMD_START_SYNC          = 0x08
    CMD_POWERDOWN           = 0x02
    CMD_RDATA               = 0x10
    CMD_RREG                = 0x20
    CMD_WREG                = 0x40

    MUX_MASK                = 0x1F
    MUX_DIF_0_1             = 0x00
    MUX_DIF_0_2             = 0x10
    MUX_DIF_0_3             = 0x20
    MUX_DIF_1_0             = 0x30
    MUX_DIF_1_2             = 0x40
    MUX_DIF_1_3             = 0x50
    MUX_DIF_2_3             = 0x60
    MUX_DIF_3_2             = 0x70
    MUX_SINGLE_0            = 0x80
    MUX_SINGLE_1            = 0x90
    MUX_SINGLE_2            = 0xa0
    MUX_SINGLE_3            = 0xb0
    MUX_REFPmREFN           = 0xc0
    MUX_AVDDmAVSS           = 0xd0
    MUX_SHORTED             = 0xe0

    GAIN_MASK               = 0xF3
    GAIN_1                  = 0x00
    GAIN_2                  = 0x10
    GAIN_4                  = 0x20
    GAIN_8                  = 0x30
    GAIN_16                 = 0x40
    GAIN_32                 = 0x50
    GAIN_64                 = 0x60
    GAIN_128                = 0x70

    PGA_DISABLED            = 0x1
    PGA_ENABLED             = 0x0

    DATA_RATE_MASK          = 0xF3
    DATA_RATE_20SPS         = 0x00
    DATA_RATE_45SPS         = 0x10
    DATA_RATE_90SPS         = 0x20
    DATA_RATE_175SPS        = 0x30
    DATA_RATE_330SPS        = 0x40
    DATA_RATE_600SPS        = 0x50
    DATA_RATE_1000SPS       = 0x60

    OP_MODE_NORMAL          = 0x00
    OP_MODE_TURBO           = 0x10

    MODE_MASK               = 0xFD
    MODE_SINGLESHOT         = 0x00
    MODE_CONTINUOUS         = 0x02

    VREF_INTERNAL           = 0x00
    VREF_EXTERNAL           = 0x10
    VREF_AVDD               = 0x20

    ### TEMP SENSOR MODE
    TEMP_SENSOR_OFF         = 0x00
    TEMP_SENSOR_ON          = 0x10
    
    #### --- Configuration Register 2
    ### DATA COUNTER ENABLE
    DCNT_DISABLE            = 0x00
    DCNT_ENABLE             = 0x10

    ### DATA INTEGRITY CHECK
    CRC_DISABLED            = 0x00
    CRC_INVERTED            = 0x10
    CRC_CRC16_ENABLED       = 0x20

    ### BURNOUT CURRENT SOURCE
    BURN_OUT_CURRENT_OFF    = 0x00
    BURN_OUT_CURRENT_ON     = 0x10

    ### IDAC CURRENT SETTING
    IDAC_CURRENT_OFF        = 0x00
    IDAC_CURRENT_10_UA      = 0x10
    IDAC_CURRENT_50_UA      = 0x20
    IDAC_CURRENT_100_UA     = 0x30
    IDAC_CURRENT_250_UA     = 0x40
    IDAC_CURRENT_500_UA     = 0x50
    IDAC_CURRENT_1000_UA    = 0x60
    IDAC_CURRENT_1500_UA    = 0x70

    #### --- Configuration Register 3
    ### IDAC1 ROUTING CONFIGURATION
    IDAC1_DISABLED          = 0x00
    IDAC1_AIN0              = 0x10
    IDAC1_AIN1              = 0x20
    IDAC1_AIN2              = 0x30
    IDAC1_AIN3              = 0x40
    IDAC1_REFP              = 0x50
    IDAC1_REFN              = 0x60

    ### IDAC2 ROUTING CONFIGURATION
    IDAC2_DISABLED          = 0x00
    IDAC2_AIN0              = 0x10
    IDAC2_AIN1              = 0x20
    IDAC2_AIN2              = 0x30
    IDAC2_AIN3              = 0x40
    IDAC2_REFP              = 0x50
    IDAC2_REFN              = 0x60


    def write_command(self, reg, cmd):
        write_command = 0x40 | (reg << 2)
        self.bus.write_byte(self.i2c_adr, write_command, cmd)

    def send_command(self, cmd):
        self.bus.write_byte(self.i2c_adr, cmd)

    def read_registers(self, reg, size):
        write = i2c_msg.write(self.i2c_adr, [reg])
        read = i2c_msg.read(self.i2c_adr, size)
        self.bus.i2c_rdwr(write, read)
        return list(read)

    def send_command(self, cmd):
        self.bus.write_byte(self.i2c_adr, cmd)

    def start(self):
        self.send_command(0x08)

    def reset(self):
        self.send_command(0x06)

    def powerdown(self):
        self.write_command(self.CMD_POWERDOWN)

    def config(self, mux=MUX_SINGLE_2, gain=GAIN_1, datarate=DATA_RATE_90SPS, mode=MODE_CONTINUOUS, ref=VREF_EXTERNAL, pga=PGA_DISABLED, op_mode=OP_MODE_NORMAL, temp=TEMP_SENSOR_OFF, dcount=DCNT_DISABLE, crc=CRC_DISABLED, bcurrent=BURN_OUT_CURRENT_OFF, idac=IDAC_CURRENT_OFF, idac1=IDAC1_DISABLED, idac2=IDAC2_DISABLED): 
        value = mux | gain | datarate | mode | ref | pga | op_mode | temp | dcount | crc | bcurrent | idac | idac1 | idac2
        self.bus.write_byte_data(self.i2c_adr, self.CMD_WREG, value)

    def ready(self):
        buffer = self.read_registers(self.CMD_RREG | 4, 1)
        return buffer[0] & 0x80

    def waitForResult(self):
        if self.rdyPin > 0:
            GPIO.wait_for_edge(self.rdyPin, GPIO.FALLING)
        else:
            while not self.ready():
                sleep(0.0005)

    def result(self):
        buffer = self.read_registers(self.CMD_RDATA, 3)
        value = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2])
        if value >= 0x800000:
            value = value - 0x1000000
        return value

    def callback(self, callbackFunction):
        GPIO.add_event_detect(self.rdyPin, GPIO.FALLING, callback=lambda _: callbackFunction())

    def __init__(self, port=1, address=0x45, rdyPin=0):
        # print("_INIT_")
        self.i2c_adr = address  # 0x40
        self.bus = SMBus(port, True)
        self.rdyPin = rdyPin
        if rdyPin > 0:
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(rdyPin, GPIO.IN)

    def __enter__(self):
        # print("_ENTER_")
        return self

    def __del__(self):
        # print("_DEL_")
        self.bus.close()

    def __exit__(self, exc_type, exc_value, traceback):
        # print("_EXIT_")
        self.bus.close()

这是我使用的代码

from time import sleep
from ADS122C04_lib import ADS122C04

ads=ADS122C04( rdyPin=4 )

ads.reset()
ads.config(ads.MUX_SINGLE_2, ads.GAIN_1, ads.DATA_RATE_90SPS, ads.MODE_CONTINUOUS, ads.VREF_EXTERNAL, ads.PGA_DISABLED, ads.OP_MODE_NORMAL, ads.TEMP_SENSOR_OFF, ads.DCNT_DISABLE, ads.CRC_DISABLED, ads.BURN_OUT_CURRENT_OFF, ads.IDAC_CURRENT_OFF, ads.IDAC1_DISABLED, ads.IDAC2_DISABLED)	
ads.start()
try:
    while True:
        result = ads.result()
        print(result)
        sleep(1)  # Adjust the sleep duration as needed
except KeyboardInterrupt:
     pass

请帮助

谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Sayali:

    以下网址为 https://www.ti.com/tool/download/SBAC299、我们提供了 ADS122C04的示例 C 代码 

    您是否验证您是否正确设置了器件、并通过正确的 MUX 设置循环来读取您的值?  

    您是否使用过逻辑分析仪或示波器来验证与器件的 I2C 通信是否正常运行并与数据表的规格匹配?

    此外、您还尝试过使用数字万用表或示波器探测输入引脚、以查看输入引脚处存在的电压是什么样的?

    此致、

    天使

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、我检查输入电压是否正确、i2c 通信也能正常工作。 但我也会得到一些随机输出、但输入的变化会保持不变。

    我检查了每件事,但我缺少什么,这就是为什么我没有得到适当的输出,但我没有得到。 因此、请查看我的代码和电路、并帮助我找出 我 遗漏的确切内容。

    在这里、我将再次共享 我的代码和电路  

    这是库文件

    import RPi.GPIO as GPIO
    from time import sleep
    from smbus2 import SMBus, i2c_msg
    
    class ADS122C04:
        CMD_RESET               = 0x06
        CMD_START_SYNC          = 0x08
        CMD_POWERDOWN           = 0x02
        CMD_RDATA               = 0x10
        CMD_RREG                = 0x20
        CMD_WREG                = 0x40
    
        #MUX_MASK                = 0x1F
        MUX_DIF_0_1             = 0x0
        MUX_DIF_0_2             = 0x1
        MUX_DIF_0_3             = 0x2
        MUX_DIF_1_0             = 0x3
        MUX_DIF_1_2             = 0x4
        MUX_DIF_1_3             = 0x5
        MUX_DIF_2_3             = 0x6
        MUX_DIF_3_2             = 0x7
        MUX_SINGLE_0            = 0x8
        MUX_SINGLE_1            = 0x9
        MUX_SINGLE_2            = 0xa
        MUX_SINGLE_3            = 0xb
        MUX_REFPmREFN           = 0xc
        MUX_AVDDmAVSS           = 0xd
        MUX_SHORTED             = 0xe
    
        #GAIN_MASK               = 0xF3
        GAIN_1                  = 0x0
        GAIN_2                  = 0x1
        GAIN_4                  = 0x2
        GAIN_8                  = 0x3
        GAIN_16                 = 0x4
        GAIN_32                 = 0x5
        GAIN_64                 = 0x6
        GAIN_128                = 0x7
    
        PGA_DISABLED            = 0x1
        PGA_ENABLED             = 0x0
    
        #DATA_RATE_MASK          = 0xF3
        DATA_RATE_20SPS         = 0x0
        DATA_RATE_45SPS         = 0x1
        DATA_RATE_90SPS         = 0x2
        DATA_RATE_175SPS        = 0x3
        DATA_RATE_330SPS        = 0x4
        DATA_RATE_600SPS        = 0x5
        DATA_RATE_1000SPS       = 0x6
    
        OP_MODE_NORMAL          = 0x0
        OP_MODE_TURBO           = 0x1
    
        #MODE_MASK               = 0xFD
        MODE_SINGLESHOT         = 0x0
        MODE_CONTINUOUS         = 0x1
    
        VREF_INTERNAL           = 0x0
        VREF_EXTERNAL           = 0x1
        VREF_AVDD               = 0x2
    
        ### TEMP SENSOR MOD
        TEMP_SENSOR_OFF         = 0x0
        TEMP_SENSOR_ON          = 0x1
        
        #### --- Configuration Register 2
        ### DATA COUNTER ENABLE
        DCNT_DISABLE            = 0x0
        DCNT_ENABLE             = 0x1
    
        ### DATA INTEGRITY CHECK
        CRC_DISABLED            = 0x0
        CRC_INVERTED            = 0x1
        CRC_CRC16_ENABLED       = 0x2
    
        ### BURNOUT CURRENT SOURCE
        BURN_OUT_CURRENT_OFF    = 0x0
        BURN_OUT_CURRENT_ON     = 0x1
    
        ### IDAC CURRENT SETTING
        IDAC_CURRENT_OFF        = 0x0
        IDAC_CURRENT_10_UA      = 0x1
        IDAC_CURRENT_50_UA      = 0x2
        IDAC_CURRENT_100_UA     = 0x3
        IDAC_CURRENT_250_UA     = 0x4
        IDAC_CURRENT_500_UA     = 0x5
        IDAC_CURRENT_1000_UA    = 0x6
        IDAC_CURRENT_1500_UA    = 0x7
    
        #### --- Configuration Register 3
        ### IDAC1 ROUTING CONFIGURATION
        IDAC1_DISABLED          = 0x0
        IDAC1_AIN0              = 0x1
        IDAC1_AIN1              = 0x2
        IDAC1_AIN2              = 0x3
        IDAC1_AIN3              = 0x4
        IDAC1_REFP              = 0x5
        IDAC1_REFN              = 0x6
        ### IDAC2 ROUTING CONFIGURATION
        IDAC2_DISABLED          = 0x0
        IDAC2_AIN0              = 0x1
        IDAC2_AIN1              = 0x2
        IDAC2_AIN2              = 0x3
        IDAC2_AIN3              = 0x4
        IDAC2_REFP              = 0x5
        IDAC2_REFN              = 0x6
    
        def write_command(self, cmd):
            self.bus.write_byte(self.i2c_adr, cmd)
    
        
        def read_registers(self, reg, size):
            write_msg = i2c_msg.write(self.i2c_adr, [reg])
            read_msg = i2c_msg.read(self.i2c_adr, size)
            self.bus.i2c_rdwr(write_msg, read_msg)
            return list(read_msg)
    
        
        def start(self):
            self.write_command(self.CMD_START_SYNC)
    
        def reset(self):
            self.write_command(self.CMD_RESET)
    
        def powerdown(self):
            self.write_command(self.CMD_POWERDOWN)
    
        def config(self, mux=MUX_SINGLE_2, gain=GAIN_1, datarate=DATA_RATE_20SPS, mode=MODE_CONTINUOUS, ref=VREF_EXTERNAL, pga=PGA_DISABLED, op_mode=OP_MODE_NORMAL, temp=TEMP_SENSOR_OFF, dcount=DCNT_DISABLE, crc=CRC_DISABLED, bcurrent=BURN_OUT_CURRENT_OFF, idac=IDAC_CURRENT_OFF, idac1=IDAC1_DISABLED, idac2=IDAC2_DISABLED): 
            value = mux | gain | datarate | mode | ref | pga | op_mode | temp | dcount | crc | bcurrent | idac | idac1 | idac2
            self.bus.write_byte_data(self.i2c_adr, self.CMD_WREG, value)
    
        def ready(self):
            buffer = self.read_registers(self.CMD_RREG | 4, 1)
            return buffer[0] & 0x80
    
        def waitForResult(self):
            if self.rdyPin > 0:
                GPIO.wait_for_edge(self.rdyPin, GPIO.FALLING)
            else:
                while not self.ready():
                    sleep(0.0001)
    
        def result(self):
            buffer = self.read_registers(self.CMD_RDATA, 3)
            value = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2])
            if value >= 0x800000:
                value = value - 0x1000000
            return value
    
    
        def callback(self, callbackFunction):
            GPIO.add_event_detect(self.rdyPin, GPIO.FALLING, callback=lambda _: callbackFunction())
    
        def __init__(self, port=1, address=0x40, rdyPin=0):
            # print("_INIT_")
            self.i2c_adr = address  # 0x40
            self.bus = SMBus(port, True)
            self.rdyPin = rdyPin
            if rdyPin > 0:
                GPIO.setmode(GPIO.BCM)
                GPIO.setup(rdyPin, GPIO.IN)
    
        def __enter__(self):
            # print("_ENTER_")
            return self
    
        def __del__(self):
            # print("_DEL_")
            self.bus.close()
    
        def __exit__(self, exc_type, exc_value, traceback):
            # print("_EXIT_")
            self.bus.close()
    

    这是我使用的主代码

    from time import sleep
    from ADS122C04_lib import ADS122C04
    
    ads=ADS122C04()
    
    ads.reset()
    ads.config(ads.MUX_SINGLE_2, ads.GAIN_1, ads.DATA_RATE_20SPS, ads.MODE_CONTINUOUS, ads.VREF_EXTERNAL, ads.PGA_DISABLED, ads.OP_MODE_NORMAL, ads.TEMP_SENSOR_OFF, ads.DCNT_DISABLE, ads.CRC_DISABLED, ads.BURN_OUT_CURRENT_OFF, ads.IDAC_CURRENT_OFF, ads.IDAC1_DISABLED, ads.IDAC2_DISABLED)	
    ads.start()
    try:
        while True:
            result = ads.result()
            print(result)
            sleep(1)  # Adjust the sleep duration as needed
    except KeyboardInterrupt:
         pass

    在这里、我得到的输出是

    请帮助我找到 ADS122C04的正确配置。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Sayali:

    此设置的问题在于、光电二极管电路上没有偏置。  

    当您在没有任何偏置电压的情况下操作光电二极管时、在其上照射的光线会在其端子上生成非常小的电压。

    读取光电二极管值的最常用方法是使用跨阻放大器电路并使用该电路的电压输出作为 ADC 的输入。  

    以下资源可帮助说明此概念以及如何实现此电路配置:

    光电二极管放大器电路|视频| TI.com

    在汽车显示屏中使用光电二极管放大器进行环境光检测(修订版 A)

    或者、您可以在反向偏置模式下对光电二极管尝试以下方法:

    此模式下通常使用光电二极管、其中施加了电压、ADC 的输入将位于电阻器和二极管之间、如图所示。

    此致、

    天使

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您的快速响应。 它对我有很大帮助。

    我 在反向偏置模式下使用光电二极管。使用万用表我检查电压是否正常、没有光落在  光电二极管上我得到的电阻器和二极管之间的电压是0.07V、有光落在光电二极管上我得到的电 阻器和二极管之间的电压是最大值。  3.48V。

    我 在电阻器和二极管之间施加了该电压作为 ADC 通道 AIN2的输入、但仍然获得恒定的输出



    请建议我使用的代码是可以的或者对 python 库和 ADS122C04代码进行的任何更改。电路中的任何其他更改。

    请帮助我解决此问题。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!
       我连接如下
    A0和 A1连接到地
    复位连接到3.3V
    DGND 和 AVSS 接地
    REFN 接地
    REFP 连接到 o.1uf 电容与接地之间的3.3V IN
    AVDD 连接到 o.1uf 电容与接地之间的3.3V IN
    DVDD 连接到 o.1uf 电容与接地之间的3.3V IN
    DRDY 连接至2.2K 上拉电阻器
    SDA 连接到2.2K 上拉电阻器
    SDL 已连接至2.2K 上拉电阻器

    现在、请帮助我弄清代码端或电路端出现了问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Sayali

    从您的描述和原理图可以看出、该电路应该没问题。

    [报价 userid="604873" url="~/support/data-converters-group/data-converters/f/data-converters-forum/1357329/ads122c04-adc-reading-photodiode-constant-output-interacing-adc-with-raspberry-pi-4-using-i2c-review-circuit-and-code/5180736 #5180736"]我得到 电阻器和 二极管之间的电压为0.07V,在光电二极管上有光照时,我得到 电阻器和二极管之间的电压为最大值。  3.48V [/报价]

    请记住、如果您的电源和 VREF 为3.3V、则 ADC 无法读取高于此电压的输入电压、因此如果模拟输入电压达到3.48V、请考虑这一点。 您可能需要修改电源电压或光电二极管电路、使其处于适当的范围内。  

    如果您无法获得正确的 ADC 读数、但使用万用表验证了电压、那么您的软件可能存在问题。  

    我建议使用逻辑分析仪或示波器探测您的数字通信线路、以验证所看到的数字通信是否与您的代码相符、并且符合与器件通信的数据表规格。

    此致、

    天使