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.
Hii,
I am trying to read photodiode value using ADS122C04 using raspberry pi4 with i2c.But i am getting constant output as change in input(Photodiode value).
Please correct me if any change in circuit i am using following circuit..
The following is the library for ADS122C04 i am using
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()
This is code i am using
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
Please Help
Thanks,
Hi Sayali,
We have example C code for the ADS122C04 available here: https://www.ti.com/tool/download/SBAC299
Are you verifying you are setting the device properly and cycling through the right MUX settings for reading your values?
Have you used a logic analyzer or oscilloscope to verify that your I2C communications to the device are working properly and match the data sheet's specifications?
Also have you tried probing the input pins with a digital multimeter or oscilloscope to see what voltage present at the input pins looks like?
Best Regards,
Angel
yes i check i am getting proper voltage at input and i2c communication also working fine. but i am getting some random output as well but no change with change in input getting constant value.
I check everythig but something i am missing that's why i am not getting proper output but i am no getting.So please review my code and circuit and please help me to find out what exactly i am missing.
Here again i am sharing my code and circuit
This is library file
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()
This is main code i am using
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
And Here the output i am getting
Please help me to find the correct configuration for ADS122C04.
Hi Sayali,
The problem with this setup is that there is no bias on your photodiode circuitry.
When you operate a photodiode without any bias voltage, shining light on it generates a very small voltage across its terminals.
The most common way to read photodiode values is to use a transimpedance amplifier circuit and use the voltage output of this circuit as the input to the ADC.
The following resources help explain this concept and how to implement this circuit configuration:
Photodiode amplifier circuit | Video | TI.com
Using Photodiode Amplifiers for Ambient Light Sensing in Automotive Displays (Rev. A)
Alternatively, you could try the following approach with the photodiode in reverse bias mode:
Photodiodes are usually used in this mode, where a voltage is applied and the input to the ADC would be between the resistor and diode as shown in the picture.
Best Regards,
Angel
Hello,
Thanks for your quick response.It helps me alot.
I use photodiode in reverse bias mode.with multimeter i check voltage it is coming correctly without light fall on photodiode i am getting voltage between the resistor and diode is 0.07V and with light fall on photodiode i am getting voltage between the resistor and diode is max. 3.48V.
I applied that voltage between the resistor and diode as input to ADC channel AIN2, But still i am getting constant output
Please suggest me my code is ok or any change in that python library and code for ADS122C04.Any other changes in circuit.
Please help me to resolve this issu.
Hello,
i made connection as follow
A0 and A1 connected to ground
RESET connected to 3.3V
DGND and AVSS connected to ground
REFN connected to ground
REFP connected to 3.3V in between o.1uf capacitor with ground
AVDD connected to 3.3V in between o.1uf capacitor with ground
DVDD connected to 3.3V in between o.1uf capacitor with ground
DRDY connected to 2.2K pull up resistor
SDA connected to 2.2K pull up resistor
SDL connected to 2.2K pull up resistor
Now please help me to figure out at code side or circuit side is having issue.
Hi Sayali
From your descriptions and schematic, the circuit should be okay.
i am getting voltage between the resistor and diode is 0.07V and with light fall on photodiode i am getting voltage between the resistor and diode is max. 3.48V.
Keep in mind that if your supply and VREF is 3.3V, the ADC can't read input voltages higher than this, so take this into consideration if the analog input voltage goes all the way up to 3.48V. You might have to modify either your supply voltage, or your photodiode circuitry to be within the appropriate range.
You likely have a problem with your software if you aren't able to get proper ADC readings but verified the voltages with a multimeter.
I would recommend probing your digital communication lines with a logic analyzer or a scope to verify that the digital communications seen, match what you intent to do with your code, and comply with the data sheet specifications for communicating with the device.
Best Regards,
Angel