Odd analog readings [SOLVED]

That’s really strange that it would need a 10k resistor, nowhere in the data sheet does it talk about that. It does say the TMP36’s output is low impedance, so it’s not like it’s floating around until terminated. It’s actively driven, but it’s not out of the question that it could potentially oscillate without a load… even linear voltage regulators can do that.

What happens if you put the 10k resistor from pin 2 of the TMP36 to GND? If your connection between pin 2 and A0 is a short jumper wire like in the spark example wiring image, don’t bother… but if it’s a long jumper wire it might have some effect. This is to see if the 10k is acting like a transmission line termination.

I’ve been using an analog thermistor instead of the TMP* series. I finally decided to try it on an Arduino Nano and am getting temperatures in the same range between both the Spark Core and Arduino Nano, so I think it’s just a margin-of-error sort of thing.

I did try to set my own ADC_SAMPLE_TIME (see this gist), but all it seemed to do was slow down the readings a little bit and make them fluctuate less.

When in doubt, sprinkle caps everywhere! One 0.1uF across the V+ and GND of the TMP36, and one directly from A0 to GND. In general, breadboards are pretty noisy for circuit prototyping. Tightening up the wiring on a perfboard should also help.

I really don’t think the readings should bounce around that much, especially in the case where you set up a reference voltage on A0 with a 10k/10k resistor divider.

It also might be worth a try to set up a low pass filter on the A0 input using a 10k ohm resistor between TMP36 pin 2 and A0 (instead of the jumper wire), and a 0.1uf capacitor between A0 and GND.

Figuring more data might be helpful here’s the results of my similar experimentation using the TMP36. As background, I have a 0.1uF decoupling cap across pins 1&3 of the TMP36 and have modified the sketch so I take 100 readings and average them before reporting them as a variable via the cloud. In all cases I’m monitoring the voltage of the 3.3v pin and it runs around 3.28v.

Case 1: Multimeter reading of the TMP36 output voltage without it being hooked to the Core – I get 0.718 volts which works out to be 21.8 degrees C, probably close to ambient in my dining room

Case 2: Multimeter reading of the TMP36 output voltage with it also being hooked to Core pin A0 – I still get 0.718 volts. So far, so good

Case 3: Analog reading from Core pin A0 via my sketch with the multimeter still connected to the TMP36 – The multimeter still says 0.718 volts but the sketch reports the average sensor reading to be 990, which works out to be .793 volts. Strange that the Core analog input sees a significantly higher voltage than the multimeter so something is awry. (I suppose it might be related to the sampling interval @BDub reported.)

Case 4: Analog reading from Core pin A0 via my sketch with the multimeter disconnected – The sketch reports the average sensor reading to be 1128, which works out to be .904 volts. This is much higher than the actual TMP36 output voltage and if converted to temperature would be just over 40 degrees C. Certainly not ambient temperature in my dining room. Alas, I can’t say what the TMP36 is actually reporting given the multimeter is disconnected in this case.

Clearly there are two problems here – the Core isn’t accurately reporting the TMP36 voltage in the case where I can compare it to the multimeter (Case 3), and without the multimeter the value is even more in error (Case 4).

Happy to experiment further if that’d help.

1 Like

Try putting a high value resistor between A0 and GND, then do some readings. Your DMM acts like a very high impedance path to ground, which is why the ADC is more accurate with it connected.

Was having the same issue of wildly swinging values reading TMP36 from A4. Fixed it with a 0.1uF cap.

See before and after images for data collected at A4 attached to TMP36. “Before” is without a 0.1uF cap from A4 to GND - values swinging wildly in a range of 19c to 27c. With a cap everything smooths out. The “before” picture reminds me of line noise seen on my scope, a common issue when building stuff on a breadboard.

Images posted on imgur HERE.

Moral of the story (for my problems at least) - add a cap, as suggested by BDub.

Yep. Adding a .1uf cap between the analog input and GND produces the best results for me. Consistent, accurate readings from the TMP36 now. (Also @americanmcgee, I’m totally geeking out by your participation here. I’ve been a fan of your work for a long time.)

Reading Count: 360

A0 Reading
      Current : 874
      Average : 872
          Min : 857
          Max : 881
        Delta : 24

Voltage
      Current : 0.700V
      Average : 0.698V
          Min : 0.686V
          Max : 0.706V
        Delta : 0.02V

Temperature
      Current : 20.00°C / 68.00°F
      Average : 19.80°C / 67.64°F
          Min : 18.60°C / 65.48°F
          Max : 20.60°C / 69.08°F
        Delta : 2°C / 3.6°F
1 Like

We’re finally making some progress on this one! Great to hear it @Hypnopompia @americanmcgee.

Hopefully others can also try the 0.1uF cap from A0 to GND and see if there is improvement. @Disquisitioner @wgbartley @Dom

Honestly if you looked at most of my breadboards, there are 0.1uF caps stuffed in most of the power rails all over the place… lol.

Yep. Putting a 0.1uf cap between A0 and GND results in A0 readings that match what my voltmeter shows on pin 2 of the TMP36 and result in calculated temperature values that make sense (e.g., 70.2°F at my workbench). I’m already reporting the average reading across 100 points but will modify my sketch to track max/min as @Hypnopompia has done.

I generally use decoupling caps for power rails, will make it a point to start using them on analog voltage inputs too…

5 Likes

The TMP36 datasheet mentions a couple of interesting facts:

  • The max output current is 50uA. (In other words, a piddly amount.)
  • A load capacitance can cause the output to oscillate. While there is no max load cap specified, a “typical” supported value (no oscillation) appears to be 0.01uF. A 0.1uF cap might cause the output to oscillate (although it seems to work fine for some people, there’s no guarantee that this will work for everyone).

Without the cap, it’s not surprising that the ADC is getting screwy values. Looking at the TMP35 output voltage: glitch (Sorry, I appear to be too new to post inline images.) Picture with markers here.

1 Like

Gah… I guess I didn’t read everything…

Good catch on the 0.1uF. I guess we should push a value no higher than 0.01uF. I ordered one of these sensors last night just so I can play along :wink:

50uA max output current is sort of not really an issue though. While it’s not much drive, there is nothing to drive really. If you create a resistor divider to convert C to F in hardware, they seem to size it to draw about 31uA in the datasheet app note. Lots of other temp sensors have a weak output as well… but this can be affected by noise, EMI, ground bounce, etc… we are operating on a breadboard with a wifi transceiver right next to it! Going to need decoupling caps, and shielding with sensors … or get sensors that have more drive, like a 10k NTC thermistor in series with another 10k 1% resistor, and a cap on the analog input to ground. The resistors here won’t be the reason this helps though, read on.

The glitch is most likely the Wifi burst transmission coupling into the wiring. You can see the glitch occurring every 2.5ms or so. Not sure if that if that timing seems significant to the Spark Team or not. It doesn’t look like the Analog input is being turned into an high output for a cycle either (could maybe be a pull up for one cycle… maaaaybe). 10k ohm load to ground on the analog input still allows the voltage to spike up to 400mV, decaying to 0mV in about 1us. I’m also seeing a 200mV spike still with a 325 ohm load, albeit a much shorter decay. 0.1uF cap on A0 to GND seems to kill the glitch at both 10k and 325 ohm though.

I tried using the Spark.sleep(5); function to see if turning off wifi helped, and it does seem to make the glitch go away when it sleeps, but when it comes back online there is no glitch. However, the core does seem to be executing my code either… Serial1 stops, no D7 output toggling every 5 seconds. But I have a Cyan breathing light. I hacked up my Temperature Dilution Filter routine for this: http://pastebin.com/raw.php?i=VdeuE3nT so don’t look at this code too hard :wink:

1 Like

While I’d certainly expect wifi coupling to be an issue, the shape of the glitch doesn’t look like what I’d expect that to be. However, I’m not familiar with wifi, and especially the shape of the transmission envelope.

The STM32F103 docs talk about effective max input resistance for the ADC (see section, “5.3.18 12-bit ADC characteristics”). However, I don’t have the time to figure out the ADC settings used by spark, and so I have no idea if the TMP36 meets the requirements for the settings. I wish I had something like a 741 laying around, because buffering the output of the TMP36 might be an interesting test.

However, the wifi theory is probably the likeliest.

If you have a Rigol DS1052E like me, it’s only a 50MHz scope… and anything near 25MHz starts to get a little round. It doesn’t come with the best probes in the world either. Wifi is up at 2.4GHz, so you’re not going to see much of anything besides power capacitively coupling into your wiring. I could be wrong… it’s a daily truth that I accept and learn from, but it’s my best guess at this point.

For the ADC setup, please see a little analysis here from above. I don’t believe I saw a hard spec of ADC has xx impedance like some micros… more like it has really high impedance 150k ohms or so, and you can set the effective impedance through the sample rate:

So I finally collected enough data to visualise and I’m still seeing massive variation on readings. The graph below shows readings over nearly 24 hours and whilst the trend is correct it’s measuring 2-3 degrees above what I’d expect (this is probably easily explained) however its’s the odd variations that are puzzling me…

1 Like

Adding capacitance to the analog input is not the right answer because unless your also adding some significant resistor ahead of the cap to create a low pass filter in hardware… the cap is doing basically nothing except filtering some very high frequency (and low in power) noise that you wouldn’t see in your ADC reading anyways. 50uA drive current is fine using the highest sampling speed of the ADC as long as your aren’t adding additional resistance in the analog connection between the sensor and A0.

Having the RF couple back in to the analog circuit is possible… but unlikely to cause this much of a deviation in the reading. The coupling would have to be severe and there’s just not enough power there to make a difference.

The problem is most likely ground bounce when the CC3000 turns on its transmitter and starts drawing 150mA of current for a fraction of a second at the same time your sampling the analog value.

The spark core makes an attempt at providing a filtered VDDA, but does not isolate (filter) the digital ground from the analog ground. This is also highly dependent on how the board is layed out, where the high current path to and from the CC3000 is routed in relation to VSSA, etc - the schematic calls out no special handling for VSSA - its just tied to GND. (To be fair, I did not actually look at the gerbers to tell if analog ground routing was taken into consideration or not)

The decoupling capacitor on VDDA is also too large (C13), ST recommends a 10nF cap in addition to your bulk capacitance. Unless you are using a really expensive ultra low ESR 100nF cap for C13, I would change to the 10nF to improve your analog noise floor.

To test for ground bounce on VSSA, solder a jumper wire as close to VSSA is possible (STM32 Pin 8) and put on a scope probe with its GND reference connected near your temperature sensor. I bet you’ll find a 100mV or so bounce every so often with the wifi on.

All valid points @mattande, but if it were ground bounce due to I x R drop from the CC3000 powering up… adding a cap to to the input (A0 to GND) should not make any difference. Actually it should make it worse due to the cap holding voltage well and pushing the A0 pin up with respect to VSSA due to the addition of Vbounce. Yet for many people the cap is helping.

A sketch so we can talk about ground bounce… this is how I’m envisioning your description of it. I have no idea if the layout looks anything like this in reality.

If it is ground bounce, it won’t necessarily be as easy as you describe to measure it. Measuring two ground points that far apart creates a loop antenna which is perfect for picking up electromagnetic radiation (i.e., from the antenna). When you are looking for noise, it’s easy to be fooled when you see it… especially with crappy uncalibrated scope probes. Probably easier just to look at the layout and see if looks like above, and could have up to 1 ohm between the Wifi GND and uC VSSA.

Also, could add a 100k / 100k resistor divider in place of the TMP36, and see what the effect is with and without a 10k ohm in series with a 0.01uF cap directly across A0 input and VSSA on the uC, vs. 10k ohm in series with 0.01uF cap on external A0 and GND pins. If they both look the same, I would not suspect ground bounce.

2 Likes

I don’t have one of these sensors but I have used the original versions some years ago. The Analog Devices datasheet says:

Note the 0.1 μF bypass capacitor on the [power] input. This capacitor should be a ceramic type, have very short leads (surface-mount is preferable), and be located as close as possible in physical proximity to the temperature sensor supply pin. Because these temperature sensors operate on very little supply current and may be exposed to very hostile electrical environments, it is important to minimize the effects of radio frequency interference (RFI) on these devices. The effect of RFI on these temperature sensors specifically and on analog ICs in general is manifested as abnormal dc shifts in the output voltage due to the rectification of the high frequency ambient noise by the IC. When the devices are operated in the presence of high frequency radiated or conducted noise, a large value tantalum capacitor (±2.2 μF) placed across the 0.1 μF ceramic capacitor may offer additional noise immunity.

I also don’t think a cap on the output is the right idea. Has anyone tried putting the sensor in a small Faraday cage (aluminum foil works) for radiated RFI and using both 0.1 uF and 2.2 uF bypass caps for conducted RFI close to the TMP36? I would try that.

Ok, adding a new theory here on these odd analog readings…

Over in this thread:

@avidan has been having some problems with a Thermistor set up on one of the analog inputs. It’s basically a resistor divider from 3.3V to GND. After going around and round on that thread I realized I have a crappy meat probe that I wouldn’t mind Sparkulating :spark: (action verb?), so I set off last night to make it happen. To my surprise I found our old friend “odd analog readings” and recalled all of the things that we’ve come up with in this thread.

I was getting readings that were about 0.24V lower than they should be, but that makes a huge problem with thermistors.

Adding a 0.1uF cap from the A3 input to GND (and not very cleanly I might add) solved the problem and my readings were very consistently close to expected.

Going back to the ADC setup… https://community.spark.io/t/odd-analog-readings/906/21

My new theory is that adding a 0.1uF cap to the A3 input (which in this thermistor circuit has a higher impedance than is expected for the ADC setup) effectively lowers the impedance enough that the sample and hold cap inside the STM32’s ADC charges up completely. I suspect that if I changed the ADC setup to allow for higher impedances, the readings would be closer to expected… but some small level of capacitance to GND on each analog input should help in all ADC setup cases. Keep in mind the ADC’s sample and hold capacitance is only 8pF, so it doesn’t take much to charge it up, but the STM32 does need to allow enough time for that to happen as well. When it doesn’t allow enough time, lowering the impedance effectively reduces the RC time constant that governs the speed at which a capacitor charges up.

Probably still helps the noisiness of the breadboard as well.

2 Likes

Are you sure the max input impedance spec isn’t being violated? It’s pretty low.

Not sure what you mean by that, but I’m pretty sure the max impedance currently is 600 ohms.