<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LeafLabs Garden &#187; Topic: Reading the internal temperature sensor</title>
		<link>http://forums.leaflabs.com/topic.php?id=1120</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Fri, 22 Jan 2016 00:14:13 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://forums.leaflabs.com/search.php</link>
		</textInput>
		<atom:link href="http://forums.leaflabs.com/rss.php?topic=1120" rel="self" type="application/rss+xml" />

		<item>
			<title>mbolivar on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6972</link>
			<pubDate>Tue, 25 Oct 2011 10:24:03 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">6972@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Thanks! Looks great.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>tdc218 on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6951</link>
			<pubDate>Sat, 22 Oct 2011 22:14:33 +0000</pubDate>
			<dc:creator>tdc218</dc:creator>
			<guid isPermaLink="false">6951@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Done!  I'll go back and clean it up a bit more when I have a bit of time (if someone else doesn't beat me to it first).
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mbolivar on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6950</link>
			<pubDate>Sat, 22 Oct 2011 18:40:19 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">6950@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Thanks! How about putting it in the How To section?&#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;http://wiki.leaflabs.com/index.php?title=How_To_Guides&#34; rel=&#34;nofollow&#34;&#62;http://wiki.leaflabs.com/index.php?title=How_To_Guides&#60;/a&#62;
&#60;/p&#62;</description>
		</item>
		<item>
			<title>tdc218 on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6941</link>
			<pubDate>Fri, 21 Oct 2011 21:01:38 +0000</pubDate>
			<dc:creator>tdc218</dc:creator>
			<guid isPermaLink="false">6941@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I can do that.  Where would be an appropriate place to put it in the wiki?
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mbolivar on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6927</link>
			<pubDate>Thu, 20 Oct 2011 22:41:22 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">6927@http://forums.leaflabs.com/</guid>
			<description>&#60;blockquote&#62;&#60;p&#62;
If you can find time, maybe you could add a wiki page?
&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;Please do! &#60;a href=&#34;http://wiki.leaflabs.com&#34; rel=&#34;nofollow&#34;&#62;http://wiki.leaflabs.com&#60;/a&#62;
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6912</link>
			<pubDate>Thu, 20 Oct 2011 04:44:09 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">6912@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;tdc218 - It looks like you are &#60;em&#62;The Temperature Sensing Expert&#60;/em&#62; !-)&#60;/p&#62;
&#60;p&#62;Thank you for sharing your experiences.&#60;br /&#62;
It is something I've never thought to dig into (so thank you), and it looks like a very nifty *free* feature (I love free:-)&#60;/p&#62;
&#60;p&#62;If you can find time, maybe you could add a wiki page?
&#60;/p&#62;</description>
		</item>
		<item>
			<title>tdc218 on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6910</link>
			<pubDate>Wed, 19 Oct 2011 21:40:04 +0000</pubDate>
			<dc:creator>tdc218</dc:creator>
			<guid isPermaLink="false">6910@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;gbulmer - I see what you did there.  :D&#60;/p&#62;
&#60;p&#62;Your suggested code worked perfectly first try.  I had a slight concern that there might be some interaction between the setup for the temp sensor and normal analog reads so I tossed one into loop and no problem.&#60;/p&#62;
&#60;p&#62;It occurs that if one only wanted to sample the temp at long intervals, one might shut off the sensor when not in use and save a few milliamps.  Possible (but as yet untested code might be):&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;void shutdown_temperature_sensor(void)
{
  ADC-&#38;gt;regs-&#38;gt;CR2 &#38;amp;= ~ADC_CR2_TSEREFE;
}&#60;/code&#62;&#60;/pre&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6904</link>
			<pubDate>Wed, 19 Oct 2011 06:32:52 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">6904@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;tdc218 - Hot, and Very Cool (did you see what I did there? ;-)&#60;/p&#62;
&#60;p&#62;Thank you for posting the code. It seems like a great demo for anyone to try.&#60;/p&#62;
&#60;p&#62;I apologise for misreading the temperature calculation :-(&#60;/p&#62;
&#60;p&#62;As a thought ... Some of the work could get done by the functions in adc.h &#38;amp; adc.c&#60;br /&#62;
So I think the unique parts could be trimmed to:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;void setup_temperature_sensor() {
  adc_reg_map *regs = ADC1-&#38;gt;regs;

// 3. Set the TSVREFE bit in the ADC control register 2 (ADC_CR2) to wake up the
//    temperature sensor from power down mode.  Do this first &#38;#39;cause according to
//    the Datasheet section 5.3.21 it takes from 4 to 10 uS to power up the sensor.

  regs-&#38;gt;CR2 &#124;= ADC_CR2_TSEREFE;

// 2. Select a sample time of 17.1 μs
// set channel 16 sample time to 239.5 cycles
// 239.5 cycles of the ADC clock (72MHz/6=12MHz) is over 17.1us (about 20us), but no smaller
// sample time exceeds 17.1us.

  regs-&#38;gt;SMPR1 = (0b111 &#38;lt;&#38;lt; (3*6));     // set channel 16, the temp. sensor
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Using &#60;code&#62;adc_enable(ADC1);&#60;/code&#62; in &#60;code&#62;setup()&#60;/code&#62; would do the rest of setup, though I also think that is called before setup anyway.&#60;/p&#62;
&#60;p&#62;Then&#60;br /&#62;
&#60;code&#62;result = adc_read(ADC1, 16);&#60;/code&#62;&#60;br /&#62;
would get the reading.&#60;/p&#62;
&#60;p&#62;(full disclosure: I am not a member of LeafLabs staff.)
&#60;/p&#62;</description>
		</item>
		<item>
			<title>tdc218 on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6892</link>
			<pubDate>Mon, 17 Oct 2011 19:02:28 +0000</pubDate>
			<dc:creator>tdc218</dc:creator>
			<guid isPermaLink="false">6892@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Thanks for your comments.  Based on that, some further reading, and studying the adc.* code, here's some code that seems to be working:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;#include &#38;lt;stdio.h&#38;gt;
#include &#38;lt;adc.h&#38;gt;

#define LED_PIN BOARD_LED_PIN

uint16 read_temp(void)
{
  adc_reg_map *regs = ADC1-&#38;gt;regs;

// 3. Set the TSVREFE bit in the ADC control register 2 (ADC_CR2) to wake up the
//    temperature sensor from power down mode.  Do this first &#38;#39;cause according to
//    the Datasheet section 5.3.21 it takes from 4 to 10 uS to power up the sensor.

  regs-&#38;gt;CR2 &#124;= ADC_CR2_TSEREFE;

// 1. Select the ADCx_IN16 input channel.

  regs-&#38;gt;SQR1 = 0;	        // set regular channel sequence length to 1
  regs-&#38;gt;SQR3 = 0b10000;		// select channel 16

// 2. Select a sample time of 17.1 μs
// per gbulmer: set channel 16 sample time to 239.5 cycles
// 239.5 cycles of the ADC clock (72MHz/6=12MHz) is over 17.1us (about 20us), but no smaller
// sample time exceeds 17.1us.

  regs-&#38;gt;SMPR1 = (0b111 &#38;lt;&#38;lt; (3*6));

// 4. Start the ADC conversion by setting the ADON bit (or by external trigger).
//  note by virture of bit 11 being zero returns right aligned results.
// Aparently we also need SWSTART - tdc

  regs-&#38;gt;CR2 &#124;= (ADC_CR2_SWSTART &#124; ADC_CR2_ADON);

// wait for conversion to complete

    while (!(regs-&#38;gt;SR &#38;amp; ADC_SR_EOC))
	;

// 5. Read the resulting VSENSE data in the ADC data register

  return (uint16)(regs-&#38;gt;DR &#38;amp; ADC_DR_DATA);
}

void setup(void)
{
/* Set up the LED to blink  */
  pinMode(LED_PIN, OUTPUT);

// kill time until serial monitor is hooked up
  while (!(SerialUSB.isConnected() &#38;amp;&#38;amp; (SerialUSB.getDTR() &#124;&#124; SerialUSB.getRTS())))
  {
    toggleLED();
    delay(100);
  }
// show start
  if(SerialUSB.isConnected() &#38;amp;&#38;amp; (SerialUSB.getDTR() &#124;&#124; SerialUSB.getRTS()))
    SerialUSB.println(&#38;quot;Temp mon startup&#38;quot;);
}

void loop(void)
{
  uint32 tstart, tend;
  uint32 result;
  char buf[64];

  tstart = micros();
  result = read_temp();
  tend   = micros();

  sprintf(buf, &#38;quot;%04x  %08x&#38;quot;, result, tend-tstart);
  if(SerialUSB.isConnected() &#38;amp;&#38;amp; (SerialUSB.getDTR() &#124;&#124; SerialUSB.getRTS()))
    SerialUSB.println(buf);

  toggleLED();
  delay(999);
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;A couple of additional things that seem be necessary:&#60;/p&#62;
&#60;p&#62;1. according to the data sheet section 5.3.21 it takes from 4 to 10 uS to power up the sensor.  So I set the TSEREFE bit in CR2 first.&#60;/p&#62;
&#60;p&#62;2. I had to set the SWSTART bit in addition to the ADON bit to get the thing to convert.  I dug this detail out of looking at the code in adc_read().&#60;/p&#62;
&#60;p&#62;It's about 72 deg F (22.2C) in my work space right now and I'm getting pretty consistent 0x06b1/0x06b2.  If I put my finger on the chip, it steps it's way down to 0x06a7, and the frozen bolt test causes it to go higher.  This makes sense because Temperature (in °C) = {(V25 - VSENSE) / Avg_Slope} + 25.  Doing the math, VSENSE = V25 - Avg_Slope * (Temp - 25) so as the temperature goes up, VSENSE goes down, which is exactly what I'm seeing here.&#60;/p&#62;
&#60;p&#62;At some point I'm gonna stick the Maple in the refrigerator and see what kind of numbers I get.  I'd be curious to hear what results others get from running this code.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6881</link>
			<pubDate>Sun, 16 Oct 2011 11:42:52 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">6881@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;tdc218 - (I took the liberty of replacing [code] and [/code] with back quotes to preserve your code layout)&#60;/p&#62;
&#60;p&#62;I have not checked the initialisation of Maple, but the temperature sensor must be switched on, so it may be channel 16, but it isn't switched on. &#60;/p&#62;
&#60;p&#62;Further, the process described in RM0008 (section 11.10 &#34;Temperature sensor&#34;) says:&#60;br /&#62;
Reading the temperature&#60;br /&#62;
To use the sensor:&#60;br /&#62;
1.	Select the ADCx_IN16 input channel.&#60;br /&#62;
2.	Select a sample time of 17.1 μs&#60;br /&#62;
3.	Set the TSVREFE bit in the ADC control register 2 (ADC_CR2) to wake up the temperature sensor from power down mode.&#60;br /&#62;
4.	Start the ADC conversion by setting the ADON bit (or by external trigger).&#60;br /&#62;
5.	Read the resulting VSENSE data in the ADC data register&#60;br /&#62;
6.	Obtain the temperature using the following formula:&#60;br /&#62;
Temperature (in °C) = {(V25 - VSENSE) / Avg_Slope} + 25.&#60;br /&#62;
Where,&#60;br /&#62;
V25 = VSENSE value for 25° C and&#60;br /&#62;
Avg_Slope = Average Slope for curve between Temperature vs. VSENSE (given in mV/° C or μV/ °C).&#60;br /&#62;
Refer to the Electrical characteristics section for the actual values of V25 and Avg_Slope.&#60;/p&#62;
&#60;p&#62;Looking at the STM32F103xB datasheet, section 5.3.19 &#34;Temperature sensor characteristics&#34;, the slope is positive, so the value will increase with increasing temperature, and not decrease as you have explained.&#60;/p&#62;
&#60;p&#62;Also, the code you posted doesn't increase the sample time to 17.1us, which might also effect the results.&#60;br /&#62;
I think that means:&#60;br /&#62;
&#60;code&#62;ADC1-&#38;gt;regs-&#38;gt;SMPR1 = (0b111 &#38;lt;&#38;lt; (3*6)); // set channel 16 sample time to 239.5 cycles&#60;/code&#62;&#60;br /&#62;
239.5 cycles of the ADC clock (72MHz/6=12MHz) is over 17.1us (about 20us), but no smaller sample time exceeds 17.1us.&#60;br /&#62;
(The default sample time for all the ADC channels is initialised to 55.5 ADC cycles, about 4.6us, which section 11.10 says is too low)&#60;/p&#62;
&#60;p&#62;So I think the channel number should be 16, the temperature sensor switched on, and the sample delay increased to 17.1us delay.&#60;/p&#62;
&#60;p&#62;(full disclosure: I am not a member of LeafLabs staff.)
&#60;/p&#62;</description>
		</item>
		<item>
			<title>tdc218 on "Reading the internal temperature sensor"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1120#post-6878</link>
			<pubDate>Sat, 15 Oct 2011 21:19:11 +0000</pubDate>
			<dc:creator>tdc218</dc:creator>
			<guid isPermaLink="false">6878@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;So, just for grins, I wanted to learn how to read the Maple's internal temperature sensor.  I came up with the following code:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;#include &#38;lt;stdio.h&#38;gt;
#include &#38;lt;adc.h&#38;gt;
#define TEMP_CHANNEL 16
void setup(void)
{
}
void loop(void)
{
  uint16 temp;
  char buf[64];
  temp = adc_read(ADC1, TEMP_CHANNEL);
  sprintf(buf,&#38;quot;%04x&#38;quot;, temp);
  SerialUSB.println(buf);
  delay(1000);
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Now, according to RM0008 (section 11.10), the temp sensor is on ADC1 channel 16.  When I run the above code, I get an output of 4 (occasionally 3, but mostly 4).  If I make TEMP_CHANNEL 17, then I get numbers in the high 0x600/low 0x700 range that act like temperatures.  When I put my finger on the CPU (warming it up) the numbers go down, and when I set a frozen bolt on it they go up, just like one would expect.  Looking at the code for adc_read, I can't account for the off by one channel number.  Anyone have an explanation for it?
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
