LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

[PRZYKŁAD] P-NUCLEO-IKA02A1 – zestaw rozwojowy do współpracy z czujnikami gazów

Po wygenerowaniu szablonu projektu należy uzupełnić kod przykładu. Część kodu inspirowana jest paczką programową od firmy STMicroelectronics – X-CUBE-IKA02A1. Paczka dostępna jest za darmo po uprzedniej rejestracji.

W pierwszej kolejności należy dodać zmienne niezbędne w dalszej części programu. Najpierw inicjalizowane są zmienne, w których przechowywane są odczyty z przetwornika ADC. W kolejnych zmiennych przechowywane są obliczone dane dotyczące stężenia, temperatury i stężenia po kompensacji temperaturowej. W ostatniej linijce znajdują zmienne przechowujące wzmocnienie układu dopasowującego sygnał (można je zmienić zworką na nakładce) oraz czułość sensora.

uint16_t sens_val_raw = 0, sens_ref_raw = 0, sens_temp_raw = 0;
float temperatura, stezenie, stezenie_po_kompensacji;
float gain = 470000, sens = 2.207;

W pętli głównej najpierw należy pobrać wartości z przetwornika ADC. Niestety w mikrokontrolerach z serii STM32L0 nie można użyć DMA w celu pobierania wielu kanałów przetwornika. W takim wypadku należy po każdym pomiarze zmieniać kanał zapisując numer kanału do rejestru CHSELR struktury hadc.Instance.

 while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
if (HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK){
	sens_ref_raw = HAL_ADC_GetValue(&hadc);

}
hadc.Instance->CHSELR = ADC_CHANNEL_8;
HAL_ADC_Start(&hadc);
if (HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK){
	sens_val_raw = HAL_ADC_GetValue(&hadc);

}
hadc.Instance->CHSELR = ADC_CHANNEL_10;
HAL_ADC_Start(&hadc);
	if (HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK){
		sens_temp_raw = HAL_ADC_GetValue(&hadc);
	}

hadc.Instance->CHSELR = ADC_CHANNEL_4;
HAL_ADC_Start(&hadc);

...

Dysponując próbkami można wyznaczyć stężenie gazu, temperatury otoczenia oraz dokonać kompensacji temperaturowej odczytu. Do wyliczenia stężenia i temperatury użyłem następujących wzorów pochodzących z paczki X-CUBE-IKA02A1.

...

HAL_Delay(100);
	temperatura = (-1481.96+sqrt(2196200+(1.8639-3.3*sens_temp_raw/4096)/3.88*1000000));
	stezenie = ((float)sens_val_raw-sens_ref_raw)*805664/gain/sens;
	stezenie_po_kompensacji = Get_comp_gas_concentration(stezenie, (int8_t)round(temperatura));
  }
  /* USER CODE END 3 */

}

Z tej paczki pochodzi także funkcja Get_comp_gas_concentration, której zadaniem jest kompensacja błędów odczytu sensora spowodowanych wpływem temperatury otoczenia. Jako argumenty należy podać uzyskane stężenie (bez kompensacji) oraz temperaturę otoczenia w formacie 8-bitowej zmiennej typu int.

float Get_comp_gas_concentration(float gas_ppm, int8_t temp){

	//check to be in boundaries of lookup table
	if(temp+COMP_SHIFT>=LOOKUP_LENGTH){
		temp=LOOKUP_LENGTH-1;
	}else if(temp+COMP_SHIFT<0){
		temp=0;
	}else{
		temp=temp+COMP_SHIFT;
	}

	return gas_ppm/TEMP_COMPENSATION[temp];
}

Także do pliku main.h należy dodać tablicę zawierającą dane konieczne do kompensacji.

/* USER CODE BEGIN Private defines */
#define LOOKUP_LENGTH 61
#define COMP_SHIFT 10 //to be able to compensate in negative temperatures
static const float TEMP_COMPENSATION[61]={0.6745, 0.6854, 0.6963, 0.7072, 0.7181, 0.7290, 0.7399, 0.7508, 0.7617, 0.7726, 0.7835, 0.7944, 0.8053, 0.8162, 0.8271, 0.8380, 0.8489, 0.8598, 0.8707, 0.8816, 0.8925, 0.9034, 0.9143, 0.9252, 0.9361, 0.9470, 0.9579, 0.9688, 0.9797, 0.9906, 1.0000, 1.0075, 1.0150, 1.0225, 1.0300, 1.0375, 1.0450, 1.0525, 1.0600, 1.0675, 1.0750, 1.0825, 1.0900, 1.0975, 1.1050, 1.1125, 1.1200, 1.1275, 1.1350, 1.1425, 1.1500, 1.1575, 1.1650, 1.1725, 1.1800, 1.1875, 1.1950, 1.2025, 1.2100, 1.2175, 1.2250};

/* USER CODE END Private defines */

Poniżej znajduje się zrzut ekranu programu STMStudio prezentujący odczyt po kompensacji w zadymionym pomieszczeniu. W normalnych warunkach (wentylowane pomieszczenie, bez żadnych źródeł czadu) odczyt nie powinien przekroczyć ok. 3 ppm.

Rys. 4. Zrzut ekranu programu STM Studio demonstrujący działanie przykładu