Měření teploty NTC pomocí STM32F

V předchozím příspěvku byly představeny NTC termistory a základní matematiku, na které jsou postaveny. V tomto příspěvku bude představen způsob, jakým je možné změřit odpor termistoru a převést ho na teplotu. Většina technik v článku popisovaných je dostatečně obecných, aby je bylo možné využít s libovolným procesorem. Konkrétní implementace bude předvedena na platformě STM32F103.

Parametry NTC termistoru, se kterým bude celý test prováděn jsou:

  • beta = 3470
  • R0 = 10 000 / 25°C

Předtím, než se programátor pustí do vlastního programování je vždy dobré, když si rozmyslí, co a jak vlastně bude dělat. Dnešní úkol je vcelku snadný, změřit napětí na odporovém děliči, přepočítat na odpor a následně na teplotu. Tuto teplotu následně vytisknout, případně něco jiného.

V předchozím zápisku byl představen vzorec, pomocí kterého je možné tento přepočet provést. Jak si ale ověřit, že je tento vzorec správný ? Vhodné je využít nějakého již existujícího nástroje – například calc, případně octave. Níže je uveden krátký skript pro octave.

beta=3470;
rref=10000;
kelvin=273.15;
tref=(kelvin + 25);
rtemp = 10000;
beta / log(rtemp / (rref * exp(-beta/tref))) - kelvin

Ze skriptu je šikovné zmínit především proměnnou rtemp, je to myšlený odpor, pro který chceme zjistit teplotu. Pro vybraný NTC termistor platí, že při teplotě 25 °C bude mít odpor přesně 10 000 ohmů. Vzorec je správný a nyní stačí napsat vlastní program pro daný mikroprocesor.

void adcSetup(void)
{
    RCC_ADCCLKConfig(RCC_PCLK2_Div2);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    ADC_InitTypeDef ntcAdcSettings;
    ntcAdcSettings.ADC_Mode = ADC_Mode_Independent;
    ntcAdcSettings.ADC_ScanConvMode = DISABLE;
    ntcAdcSettings.ADC_ContinuousConvMode = DISABLE;
    ntcAdcSettings.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ntcAdcSettings.ADC_DataAlign = ADC_DataAlign_Right;
    ntcAdcSettings.ADC_NbrOfChannel = 1;

    ADC_RegularChannelConfig(ADC1, this->adcChannel, 1, ADC_SampleTime_41Cycles5);

    ADC_Init(ADC1, &ntcAdcSettings);
    ADC_Cmd(ADC1, ENABLE);

    ADC_ResetCalibration(ADC1);
    while (ADC_GetResetCalibrationStatus(ADC1)) {}

    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1)) {}
}

V následujícím odstavci bude popsána inicializace AD převodníku.

  1. Nastavit hodiny pro AD periferii
  2. Nastavit přístup k AD periferii – číst pouze jeden kanál, pouze na vyzvání a to právě jednou
  3. Zapnutí jednoho kanálu na AD periferii
  4. Vlastní nahrání konfigurace do AD periferie
  5. Spuštění AD periferie a kalibrace

Pro více informací k jednotlivým řádkům zdrojového kódu lze vyčíst z dokumentace knihovny pro STM. Inicializace ADC je pouze prvním krokem, tím druhým je vyčtení napětí, jeho převod a přepočet na teplotu.

double getTemperature()
{
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != SET){}

    ADC_ClearFlag(ADC1, ADC_FLAG_EOC);

    uint16_t voltage = (ADC_GetConversionValue(ADC1) * VREF) / 0xFFF;
    int resistance = ((VREF - voltage) * 1000 / ((voltage / R0) * 1000.0));
    return (BETA / log(resistance / (R0 * exp(-(BETA / T0))))) - KELVIN;
}

V této části kódu se nejprve spustí převod na AD periferii a následně čeká, než se vyčtení dokončí. Následně je vhodné vyčistit flag, který poukazuje, že AD převod byl dokončen. Doba převodu je specifikována v inicializační části parametrem ADC_SampleTime_41Cycles5. Následující část kódu je už pak pouhý přepočet AD hodnoty na napětí.

Závěrem lze zmínit i to, že by samozřejmě bylo možné použít již existující knihovny, například z Arduino projektu. Tento přístup by nám ale zastínil celou řadu možných potíží, které jsou s touto problematikou spojeny.


Posted

in

by

Tags: