Tool/software:
Hi
I have an ADS1115 setup and working as intended (mostly), using the attached circuit.
I need to detect the UV light levels from a photo diode, (that side all works great)
My problem is Channel 0 fluctuates around 300 - 600 "points" while the other readings are steady and unchanged.
This makes controlling the light levels accurately near impossible, I have tested this on a few different boards so it is not just a one off.
I have read online that changing the Mux could result in problems, but this only happens for one of the 4 channels.
When I read from only one channel (any one) the levels are pretty stable, maybe fluctuating 1 or 2 points.
Strangely when I use a break point in my code to detect when the value has been changed by more than 100 there is not a problem even with the I2C line getting new values all the time, but when I ask for it from the host PC side then the break point triggers. ( Comms from Host PC to MCU are on uart 1.5M baud)
So sending a command seems to be a problem (from Host to MCU, not the ADS1115, that is running all the time) but only for Channel 0, I have tried doing this on the other channels and I have not seen the problem at all even when it would normally trigger the problem.
But if I change it to only read from one channel and the use the same commands it will not give the problem.
My code that I am using is the follows:
void UV_Process() { // need a switch case to keep this to none blocking code. unsigned char UV_ADSwrite[6]; unsigned char UV_ADSread[6]; UV_ADSwrite[0] = 0x01; // channel info setting. UV_ADSwrite[2] = 0x83; //10000011 LSB // Run to adjust / set the PWM UV level CHECK that the hood is closed first, set to ZERO unless the hood is closed. if(UV_Control.setpoint > 0 && HAL_GPIO_ReadPin(Hood_Close1_GPIO_Port, Hood_Close1_Pin) && HAL_GPIO_ReadPin(Hood_Close2_GPIO_Port, Hood_Close2_Pin)) { if(UV_CHN == 0) { //uv_dc = UV_PID_Set(&UV_Control, &UV_status); __HAL_TIM_SET_COMPARE(UV_PWM_TIM, UV_PWM_CH, UV_Control.setpoint); } } else { __HAL_TIM_SET_COMPARE(UV_PWM_TIM, UV_PWM_CH, 0); } switch(UV_reader_steps) { case(UV_send): if(UV_CHN == 0) { UV_ADSwrite[1] = 0x42; // select channel and start conversion // Try 0xC1 } else if(UV_CHN == 1) { UV_ADSwrite[1] = 0x52; // select channel and start conversion // Try 0xD1 } else if(UV_CHN == 2) { UV_ADSwrite[1] = 0x62; // select channel and start conversion // Try 0xE1 } else if(UV_CHN == 3) { UV_ADSwrite[1] = 0x72; // select channel and start conversion // Try 0xF1 } // Send the info and then move on to the next part HAL_I2C_Master_Transmit(&hi2c1, UV_ADDRESS << 1, UV_ADSwrite, 3, 100); // specify format and send data command UV_ADSwrite[0] = 0x00; HAL_I2C_Master_Transmit(&hi2c1, UV_ADDRESS << 1 , UV_ADSwrite, 1 ,100); UV_reader_steps = UV_wait; // go to next step UV_Wait = HAL_GetTick(); break; case(UV_wait): // this needs to wait until 20mS has passed for conversion to work after change of MUX Reg in ADC if((HAL_GetTick() - UV_Wait) > 20) { UV_reader_steps = UV_read; } break; case(UV_read): // get the reading HAL_I2C_Master_Receive(&hi2c1, UV_ADDRESS <<1, UV_ADSread, 2, 100); UV_Data_Send.UV_Levels[UV_CHN] = (UV_ADSread[0] << 8 | UV_ADSread[1] ); UV_reader_steps = UV_send; UV_CHN++; // go to the next channel. if(UV_CHN > 3) // loop back to the first channel. { UV_CHN = 0; if(UV_Send_Data) { // Function call to send UV data to Controller } } break; } }
Any input would be great, I have measuring between 0 and 3.3V with 4 single ended voltages.
I have tried reducing the SPS and did not have much improvement.
I would like to know if the timing and the Reg commands are setup that they do not interfere with each other, the whole code is in a super loop with other functions and processes running.
EG, does this need to be in sigle shot mode or will continuous mode work ?
MCU is STM32F103 and written in C