cancel
Showing results for 
Search instead for 
Did you mean: 

Read TCS3200 sensor frequencies with Timer Input Capture

FranzCreva
Senior

Hello everyone,

I'm trying to read the frequencies of the TCS3200 sensor, which should give frequencies according to the colors it detects.

The sensor, used with Arduino, works very well, however using it with an STM32G0 I encounter difficulties: when I activate the photodiodes to read the "green" color I receive reliable frequencies, instead if I activate the photodiodes to read blue or red I detect frequencies similar to each other, indeed, sometimes the "Blue" and "Red" frequencies are identical, but it shouldn't be like this.

I looked at the sensor datasheet and other videos on how to correctly set the input capture timer, but trying to make changes to the code the two frequencies are always similar and many times they jump (from 32000 to 80000 and other jumps of the Genre).

The part of the code with which I read the values I receive on channel 3 of the timer is this:

#define IDLE   0
#define DONE   1
#define F_CLK  64000000UL
 
uint32_t previousMillis = 0;
uint32_t currentMillis = 0;
 
uint32_t red, green, blue;
 
uint8_t stateButton;
uint8_t stateCallBack;
uint8_t stateChangeValuePin;
 
volatile uint8_t gu8_State = IDLE;
volatile uint32_t gu32_T1 = 0;
volatile uint32_t gu32_T2 = 0;
volatile uint32_t gu32_Ticks = 0;
volatile uint16_t gu16_TIM2_OVC = 0;
volatile uint32_t gu32_Freq = 0;
 
uint8_t counterRead;
 
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) {
	currentMillis = HAL_GetTick();
	if (GPIO_Pin == Button_Pin && (currentMillis - previousMillis > 100)) {
		if (stateButton == 0) {
			stateButton = 1;
			HAL_GPIO_WritePin(LedRed_GPIO_Port, LedRed_Pin, GPIO_PIN_SET);
			HAL_GPIO_WritePin(Elettrovalvola_GPIO_Port, Elettrovalvola_Pin,
					GPIO_PIN_SET);
			green=0;
			red=0;
			blue=0;
		} else {
			stateButton = 0;
			HAL_GPIO_WritePin(LedRed_GPIO_Port, LedRed_Pin, GPIO_PIN_RESET);
			HAL_GPIO_WritePin(Elettrovalvola_GPIO_Port, Elettrovalvola_Pin,
					GPIO_PIN_RESET);
		}
		previousMillis = currentMillis;
		__HAL_TIM_SET_COUNTER(&htim6, 0);
	}
}
 
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
	if (!stateButton) {
		if (stateCallBack == 0) {
			if (gu8_State == IDLE) {
				gu32_T1 = TIM3->CCR3;
				gu16_TIM2_OVC = 0;
				gu8_State = DONE;
			} else if (gu8_State == DONE) {
				gu32_T2 = TIM3->CCR3;
				gu32_Ticks = (gu32_T2 + (gu16_TIM2_OVC * 65536)) - gu32_T1;
				gu32_Freq = (uint32_t) (F_CLK / gu32_Ticks);
 
				if(counterRead>=25){
				red = gu32_Freq;
				stateCallBack = 1;
				HAL_GPIO_WritePin(S3_GPIO_Port, S3_Pin, GPIO_PIN_SET);
				counterRead=0;
				}
 
				counterRead++;
 
				__HAL_TIM_SET_COUNTER(htim, 0);
				gu8_State = IDLE;
 
			}
		} else if (stateCallBack == 1) {
			if (gu8_State == IDLE) {
				gu32_T1 = TIM3->CCR3;
				gu16_TIM2_OVC = 0;
				gu8_State = DONE;
			} else if (gu8_State == DONE) {
				gu32_T2 = TIM3->CCR3;
				gu32_Ticks = (gu32_T2 + (gu16_TIM2_OVC * 65536)) - gu32_T1;
				gu32_Freq = (uint32_t) (F_CLK / gu32_Ticks);
 
				if(counterRead>=25){
				blue = gu32_Freq;
				stateCallBack = 2;
				HAL_GPIO_WritePin(S2_GPIO_Port, S2_Pin, GPIO_PIN_SET);
				counterRead=0;
				}
 
				counterRead++;
 
				__HAL_TIM_SET_COUNTER(htim, 0);
				gu8_State = IDLE;
 
			}
		} else if (stateCallBack == 2) {
			if (gu8_State == IDLE) {
				gu32_T1 = TIM3->CCR3;
				gu16_TIM2_OVC = 0;
				gu8_State = DONE;
			} else if (gu8_State == DONE) {
				gu32_T2 = TIM3->CCR3;
				gu32_Ticks = (gu32_T2 + (gu16_TIM2_OVC * 65536)) - gu32_T1;
				gu32_Freq = (uint32_t) (F_CLK / gu32_Ticks);
 
				if(counterRead>=25){
				green = gu32_Freq;
				stateCallBack = 3;
				HAL_GPIO_WritePin(S2_GPIO_Port, S2_Pin, GPIO_PIN_RESET);
				HAL_GPIO_WritePin(S3_GPIO_Port, S3_Pin, GPIO_PIN_RESET);
				counterRead=0;
				}
 
				counterRead++;
 
				__HAL_TIM_SET_COUNTER(htim, 0);
				gu8_State = IDLE;
 
			}
		}
 
		if (stateCallBack == 3) {
			stateCallBack = 0;
		}
	}
}
 
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
	gu16_TIM2_OVC++;
}
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM6_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
 
	//HAL_TIM_Base_Start_IT(&htim3);
	HAL_TIM_Base_Start(&htim6);
 
	HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_3);
 
	HAL_GPIO_WritePin(S0_GPIO_Port, S0_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(S1_GPIO_Port, S1_Pin, GPIO_PIN_SET);
 
	HAL_GPIO_WritePin(S2_GPIO_Port, S2_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(S3_GPIO_Port, S3_Pin, GPIO_PIN_RESET);
 
  /* USER CODE END 2 */

As you can see, I wait 25 readings before saving the values I read in the variables, this is because I thought it was a problem with the sensor that was unable to deactivate/activate in time.

An example of the values I read:

G= 374269 R= 914285 B= 621359
G= 372093 R= 621359 B= 621359
G= 374269 R= 621359 B= 621359
G= 374269 R= 780487 B= 831168
G= 372093 R= 621359 B= 621359
G= 374269 R= 621359 B= 615384
G= 374269 R= 621359 B= 901408
G= 376470 R= 621359 B= 621359
G= 374269 R= 876712 B= 1488372
G= 374269 R= 621359 B= 901408
G= 372093 R= 621359 B= 621359
G= 374269 R= 955223 B= 621359

Anyone with any idea how to fix this would help me a lot.

Thanks for your attention and availability.

0 REPLIES 0