Patrick, thank you so much for all your efforts to create this video series. Your explanation of the Slope Intercept Formula was spot-on wonderful and instrumental for me. I went from clueless to educated it a very short time. It's because of your skills, I have found the solution to the ADC Temperature Conversion calculation and am sharing it. As I worked on this exercise, I used the Slope Intercept Formula as outlined in this video y=mx+b. Unfortunately, this only worked so well for me. I kept getting a temperature of 42.436 C on a chip that was actually only ~22 C. This drove me back to look more closely at the supplied source code published in the Resource Document you spoke about in video #37. After playing with the numbers, I found there's a published error in the formula!! An ERROR!! (I couldn't believe it.) Part of the issue is, the scaling ratio between VDD_CALIB and VDD_APPLI needs to be switched/reciprocated. The other part, what they don't tell you in the Reference Document is, you need to take a the voltage reading across pins 12 & 13, then multiply that reading by 100, and finally hard code the result in the pre-compiler variable VDD_APPLI. After making these two programming changes. The supplied formula works as desired. I truly can understand, Patrick, how frustrating and time consuming it must of been to try and figuring out some solution while putting this video together. I too, did a lot of head scratching. So in an effort to share this solution, I'm posting the below C Programming code and have commented it as clearly as I can make it. I hope this helps you and other who are fighting the same battle to tame the temperature sensor. ========================================================== // ---------------------------------------------------------------------------- // IMPORTANT NOTE // ---------------------------------------------------------------------------- // The below four pre-compiler variables along with the following function // CalcTempSensorReading are from the STM32F030R8T6 Reference Document. They // are needed to accurately convert the ADC Temperature Sensor voltage reading // to degrees celsius. // ---------------------------------------------------------------------------- // The following function CalcTempSensorReading contains the C Programming // source code and shows how to calculate the internal Temperature sensor // accurately. // // The below four pre-compiler variables contain static information and // are explained herein. The first two variables, TEMP110_CAL_ADDR and // TEMP30_CAL_ADDR, contain on-chip address pointers to factory loaded digital // voltage references for two temperatures: 110 degrees celsius and 30 degrees // celsius. The second two variables, VDD_CALIB and VDD_APPLI, are used by the // conversion formula, (see below function CalcTempSensorReading), to // create a ratio of voltage difference used in scaling the formula. This // scaling allows an accurate temperature value to be produced // for each specific chip regardless of it's operational environment. // // It should be noted here, that while a hard coded value of 300 is defined in // the pre-compiler variable VDD_APPLI, THE VALUE NEEDS TO BE CHANGED BY THE // PROGRAMMER. The value of VDD_APPLI represents the actual voltage supply // reading on pins 12 & 13 of the chip being flashed. A voltage reading // from a multimeter needs to be taken. That reading is then multiplied // by 100 and the result is hard coded below into the value of VDD_APPLI. // // In the source code supplied in the Reference Document, the value is 300 // used. This is an assumption from the factory that an applied voltage // across pins 12 & 13 of 3.00 volts DC is being used by the Analog to // Digital Converter (ADC). In the example below, it was found that // the supply voltage out of the ST-LinkV2 was 3.11 volts DC, so // the value 311 was hard coded into VDD_APPLI. // // The reason these VDD reading are scaled with a ratio is because of the // design of the chip. The Analog to Digital Converter (ADC) has the ability // to use a separate voltage supply other than that used by the chip. The // specifications in the Reference Document recommend this, possibly // independent, ADC VDD voltage supply be equal to or greater than // the supplied voltage for the actual chip itself (pins 1,18,19,31, // 32,63,64). (See 6.1.1 Titled: "Independent A/D converter supply // and reference voltage".) // // At the factory, the temperature sensor's ADC testing voltage has been // hard coded into VDD_CALIB. This is the ADC supply voltage used at the // factory when the calibration values were stored on chip for the // temperatures 110 and 30 degrees celsius. (These stored on-chip // calibrated values can be read at the address locations defined by the // variables TMP110_CAL_ADDR & TMP30_CAL_ADDR.) The VDD_CALIB number 330, // defined below, equates to 3.30 volts DC. // // As for the chip currently being flashed, the voltage supply to the // ADC, (pins 12 & 13), may be, and most likely is, not 3.30 volts DC. // The difference in voltage due to the chip's operating environment, // (another words, how it's wired up), needs to be taken into account // to get an accurate conversion reading to celsius. THEREFORE, THE // VALUE IN VDD_APPLI MUST BE HARD CODED BEFORE FLASHING THE CHIP. // // ---------------------------------------------------------------------------- // DECLARE PRE-COMPILER VARIABLES & MACROS // ---------------------------------------------------------------------------- #define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2)) #define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8)) #define VDD_CALIB ((uint16_t) (330)) // // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // The voltage reading, from a multimeter, across the chip pins 12 & 13 needs to be // taken. The meter's reading is then multiplied by 100. THE RESULT THEN // MUST BE HARD CODED BELOW INTO THE VALUE OF VDD_APPLI. The value 311 here // represents 3.11 volts DC. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #define VDD_APPLI ((uint16_t) (311)) // ---------------------------------------------------------------------------- // DECLARE FUNCTION - CalcTempSensorReading // ---------------------------------------------------------------------------- // Calling this function will return an "int32_t" type integer. // The returned value represents ADC temperature sensor reading converted // to degrees Celsius. // ---------------------------------------------------------------------------- int32_t CalcTempSensorReading(void) { /* Temperature sensor calibration value address */ volatile int32_t temperature; /* will contain the temperature in degree Celsius */ // ------------------------------------------------------------------------------ // IMPORTANT - THE FORMULA SUPPLIED IN THE REFERENCE DOCUMENT CONTAINS AN ERROR!. // SEE THE FOLLOWING NOTE AND CORRECTION IN THE FOLLOWING LINE OF // C PROGRAMMING CODE. // ------------------------------------------------------------------------------ // The pre-compiler variable constants VDD_CALIB and VDD_APPLI were transposed // in the next calculation. The original code example (with the error) can be // found in the STM32F030R8T6 Reference Document. See A.7.16 titled: "Temperature // computation code example" // // It was discovered through testing that the scaling done by the voltage ratio // between Calibrated and Applied is backwards. The reciprocal is needed. // ------------------------------------------------------------------------------ temperature = (((int32_t) ADC1->DR * VDD_CALIB / VDD_APPLI) - (int32_t) *TEMP30_CAL_ADDR); temperature = temperature * (int32_t) (110 - 30); temperature = temperature / (int32_t) (*TEMP110_CAL_ADDR - *TEMP30_CAL_ADDR); temperature = temperature + 30; return temperature; } // end function CalcTempSensorReading // ---------------------------------------------------------------------------- // DECLARE FUNCTION - CalcTempC2F // ---------------------------------------------------------------------------- // This function will perform the calculation required to convert the input // value from degrees celsius to degrees fahrenheit. // // It was specifically designed to be used with CalcTempSensorReading. By coding // the function below, the temperature sensor data can be retrieved in degrees // fahrenheit. // // Example: // LCDSendAnInteger( CalcTempC2F( CalcTempSensorReading() ), 4); // // ---------------------------------------------------------------------------- int CalcTempC2F(int32_t iTempInC) { /* Temperature Conversion celsius to fahrenheit */ return ((1.8 * iTempInC) + 32); } // end function CalcTempC2F
The code and formulas referenced in the datasheet might have been written by a junior engineer at ST, looks like it wasn't intentional to mislead people. You can always trust the reference manual even though there might be mistakes (we're all humans anyway), but you should ensure you understand and validate every bit of information you consume from it... Especially if you write software for a company. But great video Pat!
Hello Sir, I just wanna say that you are a mentor for me in the subject of microcontroller . But i want to give u a hint about your math: You said at the end of the video that something wrong cuz when u implemented the datasheet method to get the actual temp. you got a wrong result of 16-20 degrees as you said. But that is not wrong. Cuz your raw ADC data (Which you read on your LCD) is lower than the min raw ADC data recorded on the memory for the 30 degree. So how you would get a higher temp. than 30 degree. and you raw data is lower??.so you should according to your match get 30*-6.3* = almost 23.7 degree. Thank you :D
Im using this with an stm32f407, but I get 60 C at ambient without anything running. Do you think it's normal to reach such a temperature ? It really doesn't feel like 60C... If i simply ignore the +30 offset, it suddenly makes sense. lol 0.31 (slope) * ( 1031(reading value) - 943 (factory tested@30C) ) + 30.0 = around 57C I don't understand what is going on, and I'd really appreciate some help :/ 0.31 (slope) * ( 1031(reading value) - 943 (factory tested@30C) ) + 00.0 = around 27C which sounds a bit more reasonable... Slope = 0.31 = 80/258 = (110-30) / (1201-943)
Hi, Patrick Is videos 39 and 40 missing or just numbering issue? Since I couldn't find those missing videos on your parron videos too, just want to make sure about it. Thanks a lot!
Well thought out and remarkably well presented. The video is also a tutorial in using Datasheets. An unqualified author can be forgiven for using cut and paste on source code of this complexity. In this case, the source code was possibly written "on the fly" in response to erroneous results. Whom amongst us has never been guilty of that? Cave legit (reader beware) datasheets are written by humans.
This code, and most of my code is usually a compilation of a lot of research (no pun intended). I don't just use the datasheets, mostly because this particular datasheet is not too well organized. Most bodies of work, whether programming or not, is a gathering and re-organization of others work with attribution. Since most of this work came from the datasheet's language (telling me the registers to change and how the feature functions on their block diagrams and narrative), I am generally extending the benefit of the datasheet.
Patrick, thank you so much for all your efforts to create this video series. Your explanation of the Slope Intercept Formula was spot-on wonderful and instrumental for me. I went from clueless to educated it a very short time. It's because of your skills, I have found the solution to the ADC Temperature Conversion calculation and am sharing it.
As I worked on this exercise, I used the Slope Intercept Formula as outlined in this video y=mx+b. Unfortunately, this only worked so well for me. I kept getting a temperature of 42.436 C on a chip that was actually only ~22 C. This drove me back to look more closely at the supplied source code published in the Resource Document you spoke about in video #37. After playing with the numbers, I found there's a published error in the formula!! An ERROR!! (I couldn't believe it.) Part of the issue is, the scaling ratio between VDD_CALIB and VDD_APPLI needs to be switched/reciprocated.
The other part, what they don't tell you in the Reference Document is, you need to take a the voltage reading across pins 12 & 13, then multiply that reading by 100, and finally hard code the result in the pre-compiler variable VDD_APPLI.
After making these two programming changes. The supplied formula works as desired. I truly can understand, Patrick, how frustrating and time consuming it must of been to try and figuring out some solution while putting this video together. I too, did a lot of head scratching.
So in an effort to share this solution, I'm posting the below C Programming code and have commented it as clearly as I can make it. I hope this helps you and other who are fighting the same battle to tame the temperature sensor.
==========================================================
// ----------------------------------------------------------------------------
// IMPORTANT NOTE
// ----------------------------------------------------------------------------
// The below four pre-compiler variables along with the following function
// CalcTempSensorReading are from the STM32F030R8T6 Reference Document. They
// are needed to accurately convert the ADC Temperature Sensor voltage reading
// to degrees celsius.
// ----------------------------------------------------------------------------
// The following function CalcTempSensorReading contains the C Programming
// source code and shows how to calculate the internal Temperature sensor
// accurately.
//
// The below four pre-compiler variables contain static information and
// are explained herein. The first two variables, TEMP110_CAL_ADDR and
// TEMP30_CAL_ADDR, contain on-chip address pointers to factory loaded digital
// voltage references for two temperatures: 110 degrees celsius and 30 degrees
// celsius. The second two variables, VDD_CALIB and VDD_APPLI, are used by the
// conversion formula, (see below function CalcTempSensorReading), to
// create a ratio of voltage difference used in scaling the formula. This
// scaling allows an accurate temperature value to be produced
// for each specific chip regardless of it's operational environment.
//
// It should be noted here, that while a hard coded value of 300 is defined in
// the pre-compiler variable VDD_APPLI, THE VALUE NEEDS TO BE CHANGED BY THE
// PROGRAMMER. The value of VDD_APPLI represents the actual voltage supply
// reading on pins 12 & 13 of the chip being flashed. A voltage reading
// from a multimeter needs to be taken. That reading is then multiplied
// by 100 and the result is hard coded below into the value of VDD_APPLI.
//
// In the source code supplied in the Reference Document, the value is 300
// used. This is an assumption from the factory that an applied voltage
// across pins 12 & 13 of 3.00 volts DC is being used by the Analog to
// Digital Converter (ADC). In the example below, it was found that
// the supply voltage out of the ST-LinkV2 was 3.11 volts DC, so
// the value 311 was hard coded into VDD_APPLI.
//
// The reason these VDD reading are scaled with a ratio is because of the
// design of the chip. The Analog to Digital Converter (ADC) has the ability
// to use a separate voltage supply other than that used by the chip. The
// specifications in the Reference Document recommend this, possibly
// independent, ADC VDD voltage supply be equal to or greater than
// the supplied voltage for the actual chip itself (pins 1,18,19,31,
// 32,63,64). (See 6.1.1 Titled: "Independent A/D converter supply
// and reference voltage".)
//
// At the factory, the temperature sensor's ADC testing voltage has been
// hard coded into VDD_CALIB. This is the ADC supply voltage used at the
// factory when the calibration values were stored on chip for the
// temperatures 110 and 30 degrees celsius. (These stored on-chip
// calibrated values can be read at the address locations defined by the
// variables TMP110_CAL_ADDR & TMP30_CAL_ADDR.) The VDD_CALIB number 330,
// defined below, equates to 3.30 volts DC.
//
// As for the chip currently being flashed, the voltage supply to the
// ADC, (pins 12 & 13), may be, and most likely is, not 3.30 volts DC.
// The difference in voltage due to the chip's operating environment,
// (another words, how it's wired up), needs to be taken into account
// to get an accurate conversion reading to celsius. THEREFORE, THE
// VALUE IN VDD_APPLI MUST BE HARD CODED BEFORE FLASHING THE CHIP.
//
// ----------------------------------------------------------------------------
// DECLARE PRE-COMPILER VARIABLES & MACROS
// ----------------------------------------------------------------------------
#define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2))
#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8))
#define VDD_CALIB ((uint16_t) (330))
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// The voltage reading, from a multimeter, across the chip pins 12 & 13 needs to be
// taken. The meter's reading is then multiplied by 100. THE RESULT THEN
// MUST BE HARD CODED BELOW INTO THE VALUE OF VDD_APPLI. The value 311 here
// represents 3.11 volts DC.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#define VDD_APPLI ((uint16_t) (311))
// ----------------------------------------------------------------------------
// DECLARE FUNCTION - CalcTempSensorReading
// ----------------------------------------------------------------------------
// Calling this function will return an "int32_t" type integer.
// The returned value represents ADC temperature sensor reading converted
// to degrees Celsius.
// ----------------------------------------------------------------------------
int32_t CalcTempSensorReading(void) {
/* Temperature sensor calibration value address */
volatile int32_t temperature; /* will contain the temperature in degree Celsius */
// ------------------------------------------------------------------------------
// IMPORTANT - THE FORMULA SUPPLIED IN THE REFERENCE DOCUMENT CONTAINS AN ERROR!.
// SEE THE FOLLOWING NOTE AND CORRECTION IN THE FOLLOWING LINE OF
// C PROGRAMMING CODE.
// ------------------------------------------------------------------------------
// The pre-compiler variable constants VDD_CALIB and VDD_APPLI were transposed
// in the next calculation. The original code example (with the error) can be
// found in the STM32F030R8T6 Reference Document. See A.7.16 titled: "Temperature
// computation code example"
//
// It was discovered through testing that the scaling done by the voltage ratio
// between Calibrated and Applied is backwards. The reciprocal is needed.
// ------------------------------------------------------------------------------
temperature = (((int32_t) ADC1->DR * VDD_CALIB / VDD_APPLI)
- (int32_t) *TEMP30_CAL_ADDR);
temperature = temperature * (int32_t) (110 - 30);
temperature = temperature
/ (int32_t) (*TEMP110_CAL_ADDR - *TEMP30_CAL_ADDR);
temperature = temperature + 30;
return temperature;
} // end function CalcTempSensorReading
// ----------------------------------------------------------------------------
// DECLARE FUNCTION - CalcTempC2F
// ----------------------------------------------------------------------------
// This function will perform the calculation required to convert the input
// value from degrees celsius to degrees fahrenheit.
//
// It was specifically designed to be used with CalcTempSensorReading. By coding
// the function below, the temperature sensor data can be retrieved in degrees
// fahrenheit.
//
// Example:
// LCDSendAnInteger( CalcTempC2F( CalcTempSensorReading() ), 4);
//
// ----------------------------------------------------------------------------
int CalcTempC2F(int32_t iTempInC) {
/* Temperature Conversion celsius to fahrenheit */
return ((1.8 * iTempInC) + 32);
} // end function CalcTempC2F
The code and formulas referenced in the datasheet might have been written by a junior engineer at ST, looks like it wasn't intentional to mislead people. You can always trust the reference manual even though there might be mistakes (we're all humans anyway), but you should ensure you understand and validate every bit of information you consume from it... Especially if you write software for a company. But great video Pat!
The 300/330 rescales the ADC output. I expect that the ADC range is 3.3 V but the temperature sensor has a 3.0 V reference.
Maybe the Vdd division is because they calibrated at 3.00 and not 3.30?
Hello Sir,
I just wanna say that you are a mentor for me in the subject of microcontroller .
But i want to give u a hint about your math:
You said at the end of the video that something wrong cuz when u implemented the datasheet method to get the actual temp. you got a wrong result of 16-20 degrees as you said.
But that is not wrong. Cuz your raw ADC data (Which you read on your LCD) is lower than the min raw ADC data recorded on the memory for the 30 degree. So how you would get a higher temp. than 30 degree. and you raw data is lower??.so you should according to your match get 30*-6.3* = almost 23.7 degree.
Thank you :D
Im using this with an stm32f407, but I get 60 C at ambient without anything running. Do you think it's normal to reach such a temperature ? It really doesn't feel like 60C...
If i simply ignore the +30 offset, it suddenly makes sense. lol
0.31 (slope) * ( 1031(reading value) - 943 (factory tested@30C) ) + 30.0 = around 57C I don't understand what is going on, and I'd really appreciate some help :/
0.31 (slope) * ( 1031(reading value) - 943 (factory tested@30C) ) + 00.0 = around 27C which sounds a bit more reasonable...
Slope = 0.31 = 80/258 = (110-30) / (1201-943)
Same thing here :(
Hi, Patrick
Is videos 39 and 40 missing or just numbering issue?
Since I couldn't find those missing videos on your parron videos too, just want to make sure about it.
Thanks a lot!
I found one video "ADC - Using a Potentiometer to Serve as an Analog Voltage Source" on patron page only
Looks like you skipped video 37, the playlist goes straight from 36 to 38.
Fixed. Thanks for letting me know.
300 could be a pressure value.
Well thought out and remarkably well presented. The video is also a tutorial in using Datasheets. An unqualified author can be forgiven for using cut and paste on source code of this complexity. In this case, the source code was possibly written "on the fly" in response to erroneous results. Whom amongst us has never been guilty of that? Cave legit (reader beware) datasheets are written by humans.
This code, and most of my code is usually a compilation of a lot of research (no pun intended). I don't just use the datasheets, mostly because this particular datasheet is not too well organized.
Most bodies of work, whether programming or not, is a gathering and re-organization of others work with attribution. Since most of this work came from the datasheet's language (telling me the registers to change and how the feature functions on their block diagrams and narrative), I am generally extending the benefit of the datasheet.
Your maths are totally incorrect. y=mx + b NOT y=mx
Hi Graham,
I only needed the slope. I did not use the intercept form since an offset was not needed.