This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Simple thermistor ADC reading

First off, forgive me for being a newbie at ARM programming in general. In AVR this was straight forward.

Simple thermistor

I have a circuit connected like this to the ADC (P0.01 = AnalogInput2) .

I read sensible values from the thermistor if I have this ADC setup:

NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;
sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);
sd_nvic_EnableIRQ(ADC_IRQn);

NRF_ADC->CONFIG = (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos)
	| (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos)
	| (ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos)
	| (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling <<  ADC_CONFIG_INPSEL_Pos)
	| (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos);
																				
NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;

Could someone explain me why this just works? I thought I had to use "ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling" and "ADC_CONFIG_INPSEL_AnalogInputNoPrescaling", since the divider would be half of the supply since 10kohm resistor and 1kohm thermistor would divide the voltage in half.

  • Hi, no need to apologize. We have all been newbies at some point in time.

    First of all; what supply voltage (Vdd) are you running your nRF51 on? (5 volts is way out of maximum ratings for the nRF51, which is 3.6 volts as you can see in the Product Specification in Chapter 7, Table 20). And what sort of thermistor is this? I assume it is a NTC (resistance decreases when temperature rises).

    As you may know:

    ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling will divide Vdd by two and use that as a reference voltage for your measurements. So if you use, let us say, 3.3 volts as Vdd you will have a 1.65 volts as a reference voltage.

    ADC_CONFIG_INPSEL_AnalogInputNoPrescaling will not do any scaling of your input voltage (as opposed to e.g. ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling which will divide your input by three).

    So! When you use the code you show us you will use a reference voltage of Vdd/3. Your input, Ain, will also be scaled down to Ain/3. Hence, when you use a voltage divider in a configuration like yours the input will always lie between 0V and your reference voltage. (Given that the voltage supplied at the "top" of your voltage divider is the same as Vdd)

    When you use the code that won't work it is because you scale down your reference voltage to Vdd/2, but leave Ain "unscaled". As an example. Let us say you have a Vdd at 3.3V. When you use ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling your reference voltage becomes 1.65V. Since you don't scale the input voltage the same way and use the resistor values you do Ain will have a minimum value of 1.65V. The same as the reference voltage. Then, when temperature rises the voltage on Ain will increase and rise above your reference voltage. When you do your ADC measurements this will result in a value that is always at the maximum of 1023 (if you use 10-bit resolution).

    So what you have to remember is that you always scale your input voltage down to a level that will always stay between 0V and your reference voltage.

    Make sure you read Chapter 31, "Analog to Digital Converter (ADC)", in the Reference Manual carefully to understand the ADC with reference and input voltage scaling.

    This blog also has some info on ADC and prescaling.

  • Thank you so much for this fulfilling answer! The thermistor is NJ28 NTC Thermistor,2.8mm,10K,3% and is "on top". The supply is the VDD pin, which is measured to about 3V, where the power supply comes from USB.

    My voltage on the ADC will then range from 1.5V-3V. If I put the thermistor as the 2nd resistor below the ADC connection (flip the resistors), it would range from 1.5V-0V which means the voltage will decrease with increased temperature.

    Wouldn't the ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling be relevant then?

    In short I wonder about the optimal way to do this, with minimal drain. :)

  • Flipping the resistors sounds like a very good idea. I think doing that and using ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling is the way to go.

  • Thanks again! That was my original setup actually. Plus ADC_CONFIG_INPSEL_AnalogInputNoPrescaling then. Then I must redo the calculations to be inverse that less = more :)

    A dumb question: Would increasing the resistance on both make any difference to power consumption?

  • Yes, it would simply because the current running through a high resistance is less than the current running through a low resistance. Ohms law basically. The guy in the blog i linked to, e.g., suggests mega-ohm resistors.

Related