WiFly sensor pin readings

Hi,

I’m using a WiFly as a standalone temperature transmitter. In the simplest setup, I’m using the default web client mode on the WiFly to send sensor pin readings to a page on a web server. It all works except that I’m having trouble deciphering the values it’s sending. I have a TMP36 temperature sensor on a voltage divider network connected to pin 17 (sensor 5) on the WiFly. BTW, I’ve also tried pins 19 and 20, which are WiFly sensor 3 and 2 respectively, with the same results.

Right now, the reading from the divider network is about 230 millivolts. If I use “show q 5” in command mode I get a reading of 8102BF. The manual states that the data returned from this command is microvolts and that the “8” is a marker digit. 1046A = 66239 decimal. 66239 microvolts is 66 millivolts, right? Nowhere close to the actual temp sensor output. Am I doing an incorrect conversion (hex to dec)?

Looking at the HTML output, it reports a different value for that sensor. In the same conditions as above, the HTML query going out has “104A” as the value for sensor 5 (4,170 decimal). Huh? Well, the least significant sensor bit represents 12microvolts, maybe 4170 * 12? That’s 50,040 uV, not in the ballpark either.

Regarding the HTML output, the manual states "WiFly module can send the value of the GPIO and sensor pins: The data will come as 18 bytes of ASCII HEX: <2 bytes GPIO><channel 0 thru 7 sensor data> " Elsewhere it says the HTML query will contain data that is “Sample [from the] the GPIO and ADC pins and format to ASCII hex” It doesn’t really say what the data represents (millivolts, microvolts, bitcount).

I must be missing something basic. Any ideas how I can get to a number within 5% of 230 (or 230000) from 2 bytes of ascii hex that are “104A”?

The hex to decimal conversion is correct. I haven’t played with the wifly ADCs yet, but suggest that you put several known voltages on an ADC input (e.g. 0, 200 and 400 mV) and check the results with “show q”. According to the manual, full scale (14bits) = 400 mV and so the resolution is 12 uV/bit, but there is an offset that you need to determine. See page 73 of manual, version 11/9/2011.

I agree that the description of the output values leaves a lot to be desired. If it still doesn’t make sense, I’ve found the people at Roving Networks to be very responsive to email queries.

Thanks for the info J., I’ll give them a ring…

Hmm, according to some posts I’ve read elsewhere, there’s already an onboard divider network on the sensor pins (http://www.dinnovative.com/?p=188). Some say you can expect values of about 1/3 the actual voltage on those pins…that sort of makes sense since the pins can only handle about 1/3 of the 3.3 v operating voltage. Gonna look into this more…

OK, I have some resolution on this. It’s pretty odd though…

1.) It appears that the WiFly RN-XV does have a resistor divider network onboard. Thus, there’s no need for the external divider I was using.

2.) It appears the 2 byte value being sent in the HTML client URL is microvolts, but clearly, you can’t represent 400000uV in 2 bytes. (Not sure why they don’t set it up to report an LSB count because, at 12uV per bit, you could fit that into 2 bytes) So…

3.) It also appears that the sensor pin value sent by the HTML client has the lowest 4 bits dropped!? This means a loss of 192uV of accuracy (16 * 12uV), not a problem for my purposes.

4.) The divider network onboard is made up of unknown ohm values (to me), so I had to do a little math to get a multiplier.

Based on these findings I’m able to get fairly accurate readings for my sensor. The sensor, for this example, was putting out 720mV. The HTML query was reporting 22B6 as the sensor value.

1.) I added a 0 so the sensor reading becomes 22B60 which equals 142176 decimal. That number represents microvolts as scaled by the resistor divider.

2.) I divided 720mV by 142176uV (720000/142176) and got a multiplier of 5.06, let’s call it 5.

3.) I changed the temperature of the sensor to get a new reading. Using the new reported value I added 4 bits and multiplied by 5. Whaddya know, I got a value in line with the actual output of the sensor and thus, a fairly accurate temperature value.

4.) I still need to figure out the ADC offset for better accuracy.

Seems kind of crazy…

I checked ADC (sensor) channel 7 on my WiFly, the standalone module sold by Spark Fun, by setting up an external 10K pot as a voltage divider connected to a 1.37 V regulated source. I measured the voltage input to the ADC over a range of 0-700 mV with an accurate multimeter and compared the results of the “show q 7” command.

My conclusion is that the hex values do indeed represent microvolts, with an offset of +1 mV and overall accuracy of 3%. In more detail a least squares fit to the data yields: (reported ADC value, mV) = 0.687 + 0.971*(input value, mV), with correlation coefficient R = 0.99998.

Contrary to the WiFly documentation, the reported value does not saturate at 400 mV input. The ADC works fine up to about 600 mV, then the readings simply become erroneous. For example, 698 mV input produces ADC value = 848 mV.

I didn’t investigate the HTML output. However, the bottom few bits of the ADC measurement probably aren’t very useful. It seems reasonable to consider the measurement to be accurate (after scaling) to a bit better than 1 mV, i.e. 10 bits.

Edit: updated plot to show headroom

http://www.uoxray.uoregon.edu/ADC7.JPG

Very nice! Don’t we rock? And nice to have additional headroom before saturation. Thanks J.

I checked a bit more to see what happens when the ADC “saturates”. It turns out that this happens right around 620 mV input = 600 mV as measured by ADC, so I think the manual has a typo (it states that saturation is 400 mV but probably should be 600 mV).

However, the ADC output doesn’t just saturate. Instead, the hex value output for anything above 620 mV input is cf290, which corresponds to 848528 microvolts (848 mV). To avoid misleading measurements, it would be a good idea to check for hex values of cf290 and discard them.

Finally heard back from Roving Networks. They state that the divider networks on the RN-XV sensor pins 17,19 and 20 use 470K to the pin, 100K to ground. So in theory, you could go to a sensor output of 2.2 volts before hitting the ADC saturation voltage of 400mV (conservatively). These can be unsoldered and replaced with 0 Ohm resistors to get full voltage on the sensor pins:

If you would like to disable the resister divider network for Pin 17, 19 and 20,

remove R6 and R7 for SEN2, and put a 0 ohm on R6

remove R9 and R10 for SEN3, and put a 0 ohm on R9

remove R15 and R16 for SEN5, and put a 0 ohm on R15.

Still waiting to hear about the dropped lowest 4 bits on the HTTP query…

Just got confirmation from Roving Networks that the HTML client sensor values that are passed in the GET need to be shifted 4 bits to the left. In other words, the bottom 4 bits are dropped so a value of 21A9, for example, becomes 21A90 which is equal to 137827 microvolts. So, using the resistor divider network values that I mentioned in the above post, 137827 * 5.7 = 785614 uV actual voltage on the sensor pin.

xcplanet, this excellent discovery effort should go straight into Roving Network’s manual on this module. Sad that one must rediscover the wheel for a product we pay for :slight_smile:

Could you post your module configuration? The setup for the HTML client and how the module is configured so that to periodically read the voltage divider input at sensor 5 and then pass the value to a variable ultimately using that variable in the POST URL to update your web server?

Also regarding that internal divider network which only support could confirm: is it inside the module itself (the metal housing) or is it on the RN-XV’s PCB where the module is surface mounted to?

Thank you!

Hi,

Firstly, ds18s20, have a look here: http://bjornsenfamily.com/blog/?p=69, there’s some great info on removing the resistors, if that’s what you wish to do.

Secondly, thanks so much to xcplanet and jremington. On first reading this about a month ago, I was mightily confused. But yesterday I got it working like a dream. I’d been muddling along with fairly arbitrary numbers converting the reading, which would get me OK results, but not as accurate as it should be. Thinking it through, it’s pretty straightforward, but the situation you find yourself in with only the manual from the manufacturer to guide you is very frustrating!

I’ve posted my solution using PHP here: http://www.tinkerfailure.com/2013/01/wifly-sensor-pins/

Thanks again,

Chris

tinkerfailure:
Hi,

Firstly, ds18s20, have a look here: http://bjornsenfamily.com/blog/?p=69, there’s some great info on removing the resistors, if that’s what you wish to do.

Secondly, thanks so much to xcplanet and jremington. On first reading this about a month ago, I was mightily confused. But yesterday I got it working like a dream. I’d been muddling along with fairly arbitrary numbers converting the reading, which would get me OK results, but not as accurate as it should be. Thinking it through, it’s pretty straightforward, but the situation you find yourself in with only the manual from the manufacturer to guide you is very frustrating!

I’ve posted my solution using PHP here: http://www.tinkerfailure.com/2013/01/wifly-sensor-pins/

Thanks again,

Chris

I too have read this, as well as Chris’s postings ( Great stuff btw )… However, after reading these postings, I’m

still perplexed by the inaccuracy in the measurements I get using the sensor pins ( I’ve tried pin 20 - sensor 2

and pin 17 - sensor 5 ) and I’m not seeing a way to get accurate measurements.

I understand there is a voltage divider on the pins. I can see and measure 100K to gnd and 470K to the sensor

inputs. It’s easy to see that this makes the 3.3 V compliant, since 3.3V to a sensor pin would get divided down

by 10/57 ( ~0.175 ) to supply 579mV to the RN-XV chip A/D input. This is within it’s 0-600mV range before

saturation. Likewise, when I read the sensor using “show q ”, convert from hex to dec and multiply by the

inverse 5.7 to get the converted value I can see that it is close to the measured value.

What I’m seeing is non-linearity in the conversion. Forgive me, as I’m a bit new to this. I understand the concepts but this is my first time using the RN-XV A/D.

I set up a test rig. 3.3V lab regulated supply to the RN-XV. I attached my HP DVM to the sensor 2 input pin and

applied fixed voltages. On the other end, I had the RN-XV read the sensors every 15 seconds and post them to

my PHP page, similar to what Chris had done. Here is my data.

All values are in milli Volts ( 1000mv = 1V ) As you can see, the error goes from 88 mv @ 400mv , 21mv at 800mv yet at larger input voltage 1.322V ( 1320 mv ) the A/D is off 65mv but now under voltage rather than over. Similar results are seen using sensor 2 or 5 or by reading the voltages by what is reported using “show q”. My application sensor will output voltages from about 193mv to 3200 mv. so I need accuracy over the entire range.

READINGS IN mV

The WiFly manual says you must determine the offset of the ADC. I’ve plotted your raw data and they look fine to me, with an offset of 27. You will need to ponder the scale factor.

Thanks, I was able to fit the data using least squares as you did. BTW: there is a good site for doing this http://www.neoprogrammics.com/linear_le … /index.php

When I used this, I got y = 0.834202839107x + 153.65115395 using the 5.7 scale factor value as my Y

Wouldn’t I want to apply the 5.7 scale factor to the value to accomodate for the 100k/470k resistor divider

on the input ?

tbalon:
Thanks, I was able to fit the data using least squares as you did. BTW: there is a good site for doing this http://www.neoprogrammics.com/linear_le … /index.php

When I used this, I got y = 0.834202839107x + 153.65115395

Not sure how to approach a “scale factor”…

Hm so linearity aside how is this accurate? Take your first measurement for example: running the numbers based on your least squares formula one arrives at 489.000695271014 which is not the same as 402?

Assuming 402mV is what your meters says at the sensor pin and 489.000695271014 is what the module reports I still see a huge problem, no?

The least squares approach gives you an empirical transformation that converts your measured values using the ADC into mV input. It is the inverse of the transformation shown on the plot, which is, after a tiny amount of algebra

mV (input) = (ADC value - 27.3) * 6.86

Check this using one of your data points:

(86 - 27.3)*6.86 = 402.7

which is remarkably close to 402. You should normally be reporting integer values, so the reported value is 403.

I don’t know why your assumed scale factor of 5.7 does not appear, and so I left that for you to ponder.

ds18s20:

tbalon:
Thanks, I was able to fit the data using least squares as you did. BTW: there is a good site for doing this http://www.neoprogrammics.com/linear_le … /index.php

When I used this, I got y = 0.834202839107x + 153.65115395

Not sure how to approach a “scale factor”…

Hm so linearity aside how is this accurate? Take your first measurement for example: running the numbers based on your least squares formula one arrives at 489.000695271014 which is not the same as 402?

Assuming 402mV is what your meters says at the sensor pin and 489.000695271014 is what the module reports I still see a huge problem, no?

I’m using the 3rd column ( applied 5.7 scale factor )

I rounded the numbers to the formula. I input 402 (x) 490 (y) . So, when I read a posted value of 490, it is actually ( 490 - 153.6512 ) / 0.8342 or 403 mv . For 570x 500y If I get 570, (570-153.6512)/0.8342 is 499 etc. these are off by 1mv. I suppose if I enter the actual values with more accuracy, I can fit the data closer.

A/D mV (input) = (ADC value - 154 ) * 1.2

jremington:
The least squares approach gives you an empirical transformation that converts your measured values using the ADC into mV input. It is the inverse of the transformation shown on the plot, which is, after a tiny amount of algebra

mV (input) = (ADC value - 27.3) * 6.86

Check this using one of your data points:

(86 - 27.3)*6.86 = 402.7

which is remarkably close to 402. You should normally be reporting integer values, so the reported value is 403.

I don’t know why your assumed scale factor of 5.7 does not appear, and so I left that for you to ponder.

Thanks for your comments on this… When I started I didn’t quite understand how to approach the problem, but reading your posts got me on the right track… :smiley:

So I am curious: why did jremington’s solution NOT work as stated and the 2 solutions are different, math-wise? Or did one solution NOT work period? If so which one was the theory-not-reality then?

These modules are manufactured identically (I hope). I can’t believe that each module has a unique behavior hence having to re-invent the wheel individually?