8-bit formula conversion to 10-bit formula.

Hey,
I've got a Phidget 1114 temperature sensor hooked up to my Arduino getting temperature readings.

However, I'm getting the formula for real-world values a little messed up.

The Phidget 1114 is made for an 8-bit ADC, and the formula for that is:
Temp(C) = (SensorValue/4) - 50

How do I evaluate this formula for my Arduino's 10-bit conversion?

Just realized it's as simple as creating a pseudo-8bit by dividing by 4... Thanks anyway!

Hi, i know this is an old post, but hoping you are still around! Can you explain exactly what needs to be done to get the Phidgets 1114 calculated properly in Arduino? when you say "devide by 4" to get the psuedo 8-bit, can you show an example? I have a handful of these 1114's from my Phidgets days, and I'd love to use them on my arduino!

For such sensors the normalize function looks like y = ax +b

So tempC = a * SensorValue + b

The offset b is for "calibrating the zero-point" and it was - 50 for 8 bit. Assume it is the same for the 10 bit, you can check that quite easily.

for 8 bits ADC a was 0.25 ; a 10 bits ADC has 4 times its resolution so a becomes 0.0625, resulting in the formula

float tempC = 0.625 * SensorValue - 50;

let us know your final formula.

Thanks for getting back to me. I'm not sure why I am getting wildly different results. at 70 F room temp (21.1C) I am getting a raw value from the 1114 sensor of about 295. The formula that gets me to within a degree or two of accuracy seems to be:

tempC = ((analogRead(2) / 4.2) - 50);

but that is only through trial and error, not thru actual calculations. Below is my full code; I value any feedback on why my formula seems to be so far off.

// Digital Thermometer, using a combination of LM35's (cheap, but narrower range), and 
// Phidgets 1114 sensors (-40C - 125C range). Remember that the Phidgets sensors are
// 8-bit instead of 10-bit, so the standard calculations provided by Phidgets do not
// work. The corrected calculation for sensorValue to Celcius is:
// phidgetsTempC = ((analogRead(2)/4.2) - 50);
// Also remember that to use the Phidgets sensors, you have to use the slightly
// less accurate 5v internal reference voltage, as opposed to the 1.1v option.
// This means commenting out "analogReference(INTERNAL);" if it is listed in the code,
// and making sure your multiplier for the analogRead() ports is prefixed with 5, not 1.1.

//declare variables
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 7, 8, 5, 6);

int backlight = 2;
int IRsens;
int tempC1;
int tempC2;
int tempF1;
int tempF2;
int phidgetsTempC;
int phidgetsTempF;

void setup()
{
Serial.begin(9600);
lcd.begin (19, 3);      //20 x 4 HD44780 LCD. remember it starts with 0, not 1.
pinMode(2, OUTPUT);
}

void loop(){
int span = 75;  // take x samples from sensor, to get accurate reading
int tempC1 = 0;
int tempC2 = 0;
int tempF1 = 0;
int tempF2 = 0;
int IRsens = 0;
int phidgetsTempC = 0;
int phidgetsTempF = 0;

for (int i =0; i < span; i++) 
  tempC1 = (5 * (analogRead(0) * 100.00)/1024.00);             //read the value from the sensor
  tempC2 = (5 * (analogRead(1) * 100.00)/1024.00);             //read the value from the sensor
  phidgetsTempC = ((analogRead(2)/4.2) - 50);        //Phidgets 1114 temp sensor
  IRsens = (analogRead(5));                          // LDR on Analog5, for setting backlight on/off

tempF1 = (((tempC1*9)/5)+32);
tempF2 = (((tempC2*9)/5)+32);
phidgetsTempF = (((phidgetsTempC*9)/5)+32);

 if (IRsens > 160)
  {
  digitalWrite(backlight, HIGH);
  }
  else
  {
  digitalWrite(backlight, LOW);
  }
  
lcd.setCursor(0,0);
lcd.print("Digital Thermometer");

lcd.setCursor(0,1);
lcd.print(" Inside Temp: ");
lcd.print((tempF1+tempF2)/2);   //LM35 sensors on Analog0 and 1
lcd.print(" F ");

lcd.setCursor(0,2);
lcd.print(" Outside Temp: ");
lcd.print(phidgetsTempF);      //Phidgets sensor, on Analog2
//lcd.print(analogRead(2));
lcd.print(" F ");

delay(3000);   //wait 3000ms before updating the LCD Display
}

The default analogue reference voltage is whatever is on the 5v rail. Using USB power often means the 5v rail is often quite a long way off, this upsets any calculations assuming analogread() is referenced against 5v. Use a DMM to measure the 5v line and adjust the calculations to suit.

I use USB when debugging, etc, but for actual use, I use an external power supply. When using external power, my understanding is the on-board voltage regulator maintains a more accurate (?) 5v rail, is that the case?

regardless, I will get out my meter today and compare the rail with various power sources.

EDIT: I also just noticed there was a typo in your post, and I didn't read it carefully enough. You explained the tempC = ax+b perfectly (thank you! I much prefer to actually understand the calculation, not just blindly plug it in!), and it makes perfect sense that for 10-bit vs 8-bit resolution, you have to divide by 4 (1024 to 256 = .25 resolution), but in the code example you were off by one decimal, you displayed it as 0.625 instead of 0.0625! -- I'm not faulting you for this by any means, rather pointing out my reading through the post too quickly, and blindly plugging in formulas! When I used the correct 0.0625, my tempC value comes out perfectly accurate. Thanks again for taking the time to explain the formula.

I use USB when debugging, etc, but for actual use, I use an external power supply. When using external power, my understanding is the on-board voltage regulator maintains a more accurate (?) 5v rail, is that the case?

That is going to be very specific to every different PC and every different Arduino board. The on-board +5vdc regulator has a voltage tolerance specification and the USB standard allows a certain amount of variation in it's +5vdc power and still be in compliance. For the best accuracy possible one has a few options, use a external tight tolerance hardware reference voltage reference chip. Or one could make measurements of their boards regulator voltage and have a calibration correction function in their code. The A/D feature in the Arduino is very useful but not by any means instrumentation quality. For demanding applications one should probably look into external I2C A/D converters that offer more resolution, better reference voltage, better low noise specification, etc.

Lefty

Would an external AREF like these do substantially better?

just noticed in yourt code:

[glow]int [/glow]tempC1 = 0;

tempC1 = (5 * (analogRead(0) * 100.00)/1024.00);

will result in an int despite all float's in the formula

Try changing the var's to float. ?