user19548: I've written a Arduino sketch that converts an analogue voltage to a temperature using a lookup table - code below. I've recently changed my LUT to include more values but ever since that my Serial monitor won't print out my debugging statements etc. So I limited the number of elements in the array and it was back to normal. But when I enter more debugging statements using the serial monitor, there is garbage before my statements (still readable though when I parse through it myself) or at the start nothing is printed.
I've checked that the two baud rates are the same but I just find it peculiar that if I take some of my println() statements out it runs okay. Tested everything else with a "Hello World" example but in the simple exaples the monitor works fine.
    /*
    #####PROJECT DESCRIPTION##### 
    Measures temperature with an Arduino and NTC Thermistor (10Kohms @ 25^C)                                 in a voltage divider circuit
    Since the response is non-linear, a lookup table is used since there is a non linear response 
    The values in the LUT are the predicted values of the ADC at  temperature between 6^C and 40^C
    LUT has been derived from the calibration tests
    */
    //#####CONSTANTS#####
    const int constDelay = 3000; //constant delay for program 
    const int constNoOfAnaloguePins = 2; //number of analogue pins that are to be read
    const int errReturn = 998; //error value that is returned ***CHECK FOR CONSITENT VALUE ACROSS FUNCTIONS***
    //#####VARIABLE DECLARATIONS#####
    float avgTempC; //float var to store average of multiple temp readings

    //#####SETUP PROCEDURE#####
    void setup()
    {
      //this is the Setup part of your project - this is for code that is run only ONCE at startup
      for (int analoguePinCounter = 0; analoguePinCounter < constNoOfAnaloguePins; analoguePinCounter++) //for loop to set up numerous analogue pins
      {
        pinMode(analoguePinCounter, INPUT);  //set pin mode of the analogue thermistor input
      }//end for
      analogReference(INTERNAL); //use the interval votlage of 1.1V for the ADC resolution
      Serial.begin(9600); //serial monitor baud rate
    }//end Setup function

    //#####LOOP PROCEDURE#####
    void loop()
    {
      //this is the main part of your project - put all continuously running code here
      for (int analoguePinCounter = 0; analoguePinCounter < constNoOfAnaloguePins; analoguePinCounter++) //for loop to take temp readings from each analogue pin
      {
        //get LPF average reading over 25 samples
        avgTempC = LPF(analoguePinCounter, 25);
        //print out the readings
        if (avgTempC < float(errReturn)) //there hasn't been any temps outside the range ***CHECK THE VALUE RETURNED FROM LPF IF ERROR***
        {
          Serial.print(analoguePinCounter);
          Serial.print(" | Average Temperature Readings = ");
          Serial.print(avgTempC, 2);
          Serial.println(" degC.");
          Serial.println("-------------------------");
        }
        else //avgTempC has returned X indicating an error
        {
          Serial.print(analoguePinCounter);
          Serial.println("**ERROR IN READING AVERAGE TEMP**");
          Serial.println("-------------------------");
          delay(10);
        }//end if
        delay(constDelay/2); //wait X/2 seconds until moving onto next sensor
      }//end for
      delay(constDelay); //wait X seconds until next loop
    }//end Loop function

    /*
    #####LOW PASS FILTER DESCRIPTION#####
    This function is a LPF for smoothing out signals or averaging
    It uses a static buffer to store the last "n" readings, and each time it is called,
    the oldest reading is discarded, the new reading is added, and the stack average
    value is returned.
    The buffer size is user-adjustable, but is constrained between 2 and 50
    An initialization function fills the entire buffer with the input value. 
    This is useful when the LPF function is called for the first time.
    Note: To meet the definition of a true LPF, this function must be called         at regular intervals.
    */
    //#####LOW PASS FILTER FUNCTION#####
    float LPF(int pinAnalogue, int bufferSize)
    {
      //##PRE PROCESSOR##
      #define bufferCap 75 //maximum buffer capacity
      //##CONSTANTS##
      const int constMAXERRORS = 5; //max number of error that can occur
      const int errReturn = 998; //value return if there is an error
      //##VARIABLES##
      float tempC; //var to store instantaneous temp
      static float buffer[bufferCap]; //array to act like a 'stack' of temp values ***DOES IT NEED TO BE STATIC NOW?***
      float tempSum; //to store the sum of the temperatures
      float output; //return value of LPF which is the average of the temp readings
      int errCounter = 0; //initialise error counter to 0

      //make sure buffer size is between the range
      bufferSize = constrain(bufferSize, 2, bufferCap);

      for (int i=0; i<bufferSize; i++) //for loop to store temps in buffer array 
      {
        tempC = getTempFloat(pinAnalogue); //call function to get temperature from pin
        if ((tempC > -errReturn) && (tempC < errReturn)) //no error 
        {
          buffer[i] = tempC; //store temp value into array
        }
        else //error
        {
          errCounter++; //increment counter for number of erroneous readings
          i--; //decrement counter as to not skip a sample index
          if (errCounter > constMAXERRORS)
          {
            return(errReturn+1.0); //return the error value + 1
          }//end if
        }//end if
        delay(25); //allow the ADC to settle
      }//end for

      //calculate current stack average
      tempSum = 0; //initialise sum total
      for (int i=0; i<bufferSize; i++) //go through stack array
      {
        tempSum = tempSum + buffer[i]; //total up readings
      }//end for

      //average sum
      output = tempSum/bufferSize;

      return(output);
    }//end LPF function

    /*
    #####GET TEMP FLOAT DESCRIPTION#####  
    This function converts a thermistor reading into a corresponding temp in ^C
    The thermistor is incorporated into a Voltage Divider Circuit:

       +Vref---[Thermistor]---+--[1.8K]---GND
                              |
                             ADC @ thermPin

    ADC Values were externally calculated from the calibration table using:           ADC = 1023*10000/(Rtherm+10000)
    The LUT is an array of integer constants containing the predicted ADC         values for all temperatures between +6^C to +40.5^C.
    The array index starts at zero, which corresponds to a temperature of         +6^C.
    A linear interpolation between the two closest entries is performed to         give a finer output resolution.
    */

    float getTempFloat (int thermPin)
    {
      //##CONSTANTS##
      /*1K8*/
      const int constLUTArraySize = 431;
      const int LUT_Therm[constLUTArraySize] = //LUT containing ADC values
      {
        223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C
        233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
        244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
        255, 256, 257, 258, 259, 260, 261, 263, 264, 265,
        266, 267, 268, 269, 271, 272, 273, 274, 275, 277,
        278, 279, 280, 281, 283, 284, 285, 286, 287, 289,
        290, 291, 292, 294, 295, 296, 297, 299, 300, 301,           //13^C to 13.9^C
        302, 304, 305, 306, 308, 309, 310, 312, 313, 314,
        315, 317, 318, 319, 321, 322, 323, 325, 326, 327,
        329, 330, 332, 333, 334, 336, 337, 338, 340, 341,
        343, 344, 345, 347, 348, 350, 351, 353, 354, 355,
        357, 358, 360, 361, 363, 364, 366, 367, 369, 370,
        371, 373, 374, 376, 377, 379, 380, 382, 383, 385,
        387, 388, 390, 391, 393, 394, 396, 397, 399, 400,
        402, 404, 405, 407, 408, 410, 411, 413, 415, 416,
        418, 419, 421, 423, 424, 426, 428, 429, 431, 433,
        434, 436, 438, 439, 441, 443, 444, 446, 448, 449,
        451, 453, 454, 456, 458, 460, 461, 463, 465, 466,
        468, 470, 472, 473, 475, 477, 479, 480, 482, 484,
        486, 488, 489, 491, 493, 495, 497, 498, 500, 502,
        504, 506, 507, 509, 511, 513, 515, 517, 519, 520,
        522, 524, 526, 528, 530, 532, 534, 535, 537, 539,
        541, 543, 545, 547, 549, 551, 553, 555, 557, 559,
        560, 562, 564, 566, 568, 570, 572, 574, 576, 578, 
        580, 582, 584, 586, 588, 590, 592, 594, 596, 598,
        600, 602, 604, 606, 608, 611, 613, 615, 617, 619,
        621, 623, 625, 627, 629, 631, 633, 635, 638, 640,
        642, 644, 646, 648, 650, 652, 655, 657, 659, 661,
        663, 665, 667, 670, 672, 674, 676, 678, 680, 683,
        685, 687, 689, 691, 694, 696, 698, 700, 702, 705,
        707, 709, 711, 714, 716, 718, 720, 723, 725, 727,
        729, 732, 734, 736, 738, 741, 743, 745, 747, 750, 
        752, 754, 757, 759, 761, 764, 766, 768, 771, 773,
        775, 778, 780, 782, 785, 787, 789, 792, 794, 796,
        799, 801, 803, 806, 808, 811, 813, 815, 818, 820,
        822, 825, 827, 830, 832, 834, 837, 839, 842, 844,
        847, 849, 851, 854, 856, 859, 861, 864, 866, 868,
        871, 873, 876, 878, 881, 883, 886, 888, 891, 893,
        896, 898, 901, 903, 906, 908, 911, 913, 916, 918, 
        921, 923, 926, 928, 931, 933, 936, 938, 941, 943,
        946, 948, 951, 953, 956, 958, 961, 963, 966, 969,
        971, 974, 976, 979, 981, 984, 987, 989, 992, 994,
        997, 999, 1002, 1005, 1007, 1010, 1012, 1015, 1017, 1020, //40^C to 49.9^C
        1023                                                     //50^C
      };
      const int errReturn = 998; //error value that is returned
      //##VARIABLES##
      float _tempC; //intermediate results + final temperature return value
      int ADC_Lo; //the lower ADC matching value
      int ADC_Hi; //the higher ADC matching value
      float Temp_Lo; //the lower number matching temperature
      int mapTemp_Lo; //the lower number that will be entered into the map function
      float Temp_Hi; //the higher  number matching temperature
      int mapTemp_Hi; //the higher number that will be entered into the map function

      //prep ADC onto that particular analogue pin to sort out multiplexing etc
      analogRead(thermPin); 
      delay(10);
      //get raw ADC value from VDR
      int thermValue = analogRead(thermPin); 
      //Serial.println(thermValue);
      /*Serial.print("PinNo : ");
      Serial.println(thermPin);*/
      Serial.print("ADC : ");
      Serial.println(thermValue);
      //return dummy value if the sensor reading falls outside of the LUT
      if (thermValue < LUT_Therm[0]) //less than the least ADC value
        _tempC = -errReturn-1; //under range dummy value
      else if (thermValue > LUT_Therm[constLUTArraySize-1]) //more than the greatest ADC value
        _tempC = errReturn+1; //over range dummy value
      else //value falls in LUT range
      {
        for (int i=0; i<constLUTArraySize; i++) //step through LUT and look for a match
        {    
          if (LUT_Therm[i] > thermValue) //LUT value is greater than the reading
          {  
            //find the closest higher ADC value
            ADC_Hi = LUT_Therm[i];
            //record the closest higher temperature        
            Temp_Hi = float(i/10) + 13.0; //convert to temp
            //get the closest lower temperature - taking the lower table boundary into account
            if (i != 0) //general case -> as long as it is not the first entry
            {
              ADC_Lo = LUT_Therm[i-1]; //store the previous array element as the low
              Temp_Lo = float(i/10) + 13.0 - 0.1; //convert to temp
            }
            else //special case -> counter = 0 ie first array entry
            {
              ADC_Lo = LUT_Therm[i]; //store the first array element
              Temp_Lo = i - float(i/10) + 13.0; //convert to temp
            }//end if
            //interpolate the temperature value for greater precision
            //NB the map function does not use floating-point math, so the int values of temp are multiplied by 100 and then result is subsequently divided by 100
            mapTemp_Lo = Temp_Lo*100;
            mapTemp_Hi = Temp_Hi*100;
            _tempC = float(map(thermValue,ADC_Lo,ADC_Hi,mapTemp_Lo,mapTemp_Hi))/100;
            break;  //exit for loop after the match is detected
          }//end if
        }//end for
      }//end if
      return(_tempC);
    }//end getTempFloat function

In this particular sketch no output is seen on the serial monitor. Has anyone come across this before or have any ideas how I could fix this?

user7508: I went through your program and found a few bugs you may want to fix. I
think only one of these (wastage of RAM) is really related to your
problem, but anyway, here it goes:
Fist, there are two issues with LPF(). The description states that
this is a rolling average low-pass filter. This is erroneous: a rolling
average would take a single reading, then report the average of the
last n readings. This function, in contrast, takes n readings and
reports their average. This makes a big difference: a rolling average
would need to store the last n values in static memory, while your
function does this for no good reason. You are just wasting
300 bytes of RAM.
Here is a reimplementation of LPF() that does the same thing as yours
without wasting RAM. I changed its name to be more consistent with it's
real purpose:
/*
 * Take 'count' temperature readings from 'pin' and return their average.
 * Returns NaN (not a number) if too many readings where in error.
 */
float getAvgTemp(int pin, int count)
{
  const int MAXERRORS = 5; // max number of errors that can occur
  float temp;              // current temperature reading
  float tempSum = 0;       // sum of temperatures
  int errCounter = 0;      // number of erroneous readings

  for (int i = 0; i < count; i++) {

    // Try to get a valid reading.
    do {
      temp = getTempFloat(pin);
      if (isnan(temp))
        errCounter++;
      delay(25); // allow the ADC to settle
    } while (isnan(temp) && errCounter <= MAXERRORS);

    // Too many errors: return an error.
    if (errCounter > MAXERRORS)
      return NAN;

    tempSum += temp;
  }

  return tempSum / count;
}

Here I use NaN (not a number) as an error indicator, as it is
semantically clearer than a random out-of-range value.
There are also a few errors in getTempFloat():

pgm_read_word(LUT_Therm[constLUTArraySize-1]) and
pgm_read_word(LUT_Therm[i]) will not work: you have to pass
pgm_read_word() the address where to read.
float(i/10) does not do what you want: it computes i/10 as an
integer division (i.e. discarding the fractional part), and then it
converts the result to a float. If you want a floating point division,
you should make sure that at least one of the arguments is a float.
The usual idiom is i/10.0.

Here is a version of getTempFloat() with these problems fixed, and
also somewhat simplified:
float getTempFloat(int pin)
{
  int i, lutval, prev_lutval;

  // Take an analog reading.
  analogRead(pin);  // dummy reading to settle the MUX
  delay(10);
  int adc = analogRead(pin);
  Serial.print(F("ADC: "));
  Serial.println(adc);

  // Find i such that adc lies between LUT[i-1] and LUT[i].
  for (i = 0; i < constLUTArraySize; i++) {
    prev_lutval = lutval;
    lutval = pgm_read_word(&LUT_Therm[i]);
    if (lutval >= adc) break;
  }

  // Special case: adc == LUT[0].
  if (i == 0 && adc == lutval)
    return 13.0;

  // Report an error if out of range.
  if (i == 0 || i == constLUTArraySize)
    return NAN;

  // Return interpolated temperature.
  float fraction = float(adc - prev_lutval) / (lutval - prev_lutval);
  return 13.0 + (i-1 + fraction) / 10.0;
}


Addendum
I have noticed a few more problems and inconsistencies with your
program.
Powering the thermistor from the internal reference
In setup(), you write

analogReference(INTERNAL); //use the interval votlage of 1.1V for the
  ADC resolution

and then, in a comment further down you have the schematic

+Vref---[Thermistor]---+--[1.8K]---GND

This suggests you are powering the voltage divider from the internal
voltage reference of the MCU. You should not do that, as the datasheet
states: “Note that VREF is a high impedance source, and only
a capacitive load should be connected in a system.”
Relationship between ADC reading and thermistor resistance
In the same comment as above, you wrote:

ADC = 1023*10000/(Rtherm+10000)

Actually, the factor is 1024, not 1023. Again, see the datasheet. And
the number 10000 should be 1800, i.e. the resistance you have put
between the ADC input and GND. I understand that you may have simply
changed the value and forgotten to update one of the comments. But you
should consider a misleading comment as a bug, especially if it's not
consistent with the actual code.
For this kind of measurement, you get the best precision if the pulldown
resistor has a value close to the resistance of the thermistor. The
comment at the beginning of the program says your thermistor has
10 kΩ @ 25°C. This means that, if you are mostly interested in
the range around 25°C, a 10 kΩ pulldown is better than 1.8 kΩ.
Relationship between array index and temperature
The comment before the LUT says:

The array index starts at zero, which corresponds to a temperature of
  +6^C

Then, the very first line of the LUT has the comment

//7^C to 7.9^C

And later on, the implementation of getTempFloat() assumes
index 0 means 13°C. You should sort this out and make everything
consistent.
BTW, your LUT values go all the way up to 1023. A reading of 1023 would
mean the ADC voltage is higher than 1022.5/1024×VREF. Which
in turn would imply the thermistor has a resistance lower than
14.6 Ω (assuming a 10 kΩ pulldown). I find this dubious.
Removal of the LUT
Since your program is meant to run very slowly (constDelay = 3000),
you can afford doing complex computations in it. You can get the same
precision with a way smaller LUT if you use a higher order
interpolation. For a function sampled at constant steps, the
Catmull–Rom
spline
is easy to implement and is way better than linear interpolation.
Or you can remove the LUT altogether and use an analytical expression
instead. If you derived the LUT from such an expression, why not use it
in the program? If the LUT derives from experimental data, you can try
to do an empirical fit, i.e. an arbitrary function that closely fits the
data. The most obvious (though maybe not the best) empirical function
would be a polynomial. Below is an example of such a function that
reproduces you LUT with good accuracy using a 6th degree polynomial. It
assumes the first LUT entry is for a temperature of 7°C:
float getTempFloat(int pin)
{
    const float T0 = 7;   // temperature at beginning of range
    int adc = analogRead(pin);
    float x = (adc-223.) / (1023.-223.) * 2 - 1;  // scale to [-1:1]
    if (x < -1 || x > 1) return NAN;              // out of range
    float y = 1.474 - x*(0.533 - x*(0.732 - x*0.458));
    return T0 + 26.107 + x*(19.287 - x*(3.596 - x*y));
}

Actually this may be even more accurate than your LUT-based function, as
that LUT is made of integer values whereas the calibration curve should
obviously be continuous.

user19409: You have likely run out of RAM.
You have 431 integers in the look-up table alone. That equates to 862 bytes of SRAM. You also have a buffer of 75 floats, which equates to 300 bytes. This is in addition to all your other variables and function calls. 
The Arduino Uno only has 2KB of SRAM.
Solutions:
 1) Move your LUT to Flash (ie. program space) using the PROGMEM keyword (just before the equals sign):
const int LUT_Therm[constLUTArraySize] PROGMEM = //LUT containing ADC values

2) Use an Arduino with a greater amount of SRAM. 

Arduino Mega  - 8KB SRAM  
Arduino ZERO  - 32KB SRAM  
Arduino Due   - 96KB SRAM  
Arduino MKR 1000/1010/1400/ZERO - 32KB SRAM


user14737: Use the F() macro for all double-quoted strings you print.  Change lines like this:
Serial.println(" degC.");

...to this:
Serial.println( F(" degC.") );

This will save about 100 bytes of RAM.
And as BrettAM suggested, put that table into PROGMEM:
  const int LUT_Therm[constLUTArraySize] PROGMEM = //LUT containing ADC values
  {
    223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C

This requires changing how you access the array, from this:
  if (thermValue < LUT_Therm[0]) //less than the least ADC value

...to this:
  if (thermValue < (int) pgm_read_word( &LUT_Therm[0] )) //less than the least ADC value

Note the cast, the function call and the ampersand wrapped around the desired array element.  You must replace all uses of the array with this sequence.  You can also read it once into a local int and then use it normally:
      int lut_therm = (int) pgm_read_word(LUT_Therm[i]); // read it in

      if (lut_therm > thermValue) //LUT value is greater than the reading

This saves almost 1000 bytes of RAM!  The reported binary sketch size goes up by the same amount[1].  
I had to pull the table out from inside getTempFloat, to the file scope.  Here's the complete sketch with those mods:
/*
#####PROJECT DESCRIPTION##### 
Measures temperature with an Arduino and NTC Thermistor (10Kohms @ 25^C)                                 in a voltage divider circuit
Since the response is non-linear, a lookup table is used since there is a non linear response 
The values in the LUT are the predicted values of the ADC at  temperature between 6^C and 40^C
LUT has been derived from the calibration tests
*/

//#####CONSTANTS#####
const int constDelay = 3000; //constant delay for program 
const int constNoOfAnaloguePins = 2; //number of analogue pins that are to be read
const int errReturn = 998; //error value that is returned ***CHECK FOR CONSITENT VALUE ACROSS FUNCTIONS***

//#####VARIABLE DECLARATIONS#####
float avgTempC; //float var to store average of multiple temp readings

//#####SETUP PROCEDURE#####
void setup()
{
  //this is the Setup part of your project - this is for code that is run only ONCE at startup
  for (int analoguePinCounter = 0; analoguePinCounter < constNoOfAnaloguePins; analoguePinCounter++) //for loop to set up numerous analogue pins
  {
    pinMode(analoguePinCounter, INPUT);  //set pin mode of the analogue thermistor input
  }//end for
  analogReference(INTERNAL); //use the interval votlage of 1.1V for the ADC resolution
  Serial.begin(9600); //serial monitor baud rate
}//end Setup function

//#####LOOP PROCEDURE#####
void loop()
{
  //this is the main part of your project - put all continuously running code here
  for (int analoguePinCounter = 0; analoguePinCounter < constNoOfAnaloguePins; analoguePinCounter++) //for loop to take temp readings from each analogue pin
  {
    //get LPF average reading over 25 samples
    avgTempC = LPF(analoguePinCounter, 25);
    //print out the readings
    if (avgTempC < float(errReturn)) //there hasn't been any temps outside the range ***CHECK THE VALUE RETURNED FROM LPF IF ERROR***
    {
      Serial.print(analoguePinCounter);
      Serial.print( F(" | Average Temperature Readings = ") );
      Serial.print(avgTempC, 2);
      Serial.println( F(" degC.") );
      Serial.println( F("-------------------------") );
    }
    else //avgTempC has returned X indicating an error
    {
      Serial.print(analoguePinCounter);
      Serial.println( F("**ERROR IN READING AVERAGE TEMP**") );
      Serial.println( F("-------------------------") );
      delay(10);
    }//end if
    delay(constDelay/2); //wait X/2 seconds until moving onto next sensor
  }//end for
  delay(constDelay); //wait X seconds until next loop
}//end Loop function

/*
#####LOW PASS FILTER DESCRIPTION#####
This function is a LPF for smoothing out signals or averaging
It uses a static buffer to store the last "n" readings, and each time it is called,
the oldest reading is discarded, the new reading is added, and the stack average
value is returned.
The buffer size is user-adjustable, but is constrained between 2 and 50
An initialization function fills the entire buffer with the input value. 
This is useful when the LPF function is called for the first time.
Note: To meet the definition of a true LPF, this function must be called         at regular intervals.
*/
//#####LOW PASS FILTER FUNCTION#####
float LPF(int pinAnalogue, int bufferSize)
{
  //##PRE PROCESSOR##
  #define bufferCap 75 //maximum buffer capacity
  //##CONSTANTS##
  const int constMAXERRORS = 5; //max number of error that can occur
  //##VARIABLES##
  float tempC; //var to store instantaneous temp
  static float buffer[bufferCap]; //array to act like a 'stack' of temp values ***DOES IT NEED TO BE STATIC NOW?***
  float tempSum; //to store the sum of the temperatures
  float output; //return value of LPF which is the average of the temp readings
  int errCounter = 0; //initialise error counter to 0

  //make sure buffer size is between the range
  bufferSize = constrain(bufferSize, 2, bufferCap);

  for (int i=0; i<bufferSize; i++) //for loop to store temps in buffer array 
  {
    tempC = getTempFloat(pinAnalogue); //call function to get temperature from pin
    if ((tempC > -errReturn) && (tempC < errReturn)) //no error 
    {
      buffer[i] = tempC; //store temp value into array
    }
    else //error
    {
      errCounter++; //increment counter for number of erroneous readings
      i--; //decrement counter as to not skip a sample index
      if (errCounter > constMAXERRORS)
      {
        return(errReturn+1.0); //return the error value + 1
      }//end if
    }//end if
    delay(25); //allow the ADC to settle
  }//end for

  //calculate current stack average
  tempSum = 0; //initialise sum total
  for (int i=0; i<bufferSize; i++) //go through stack array
  {
    tempSum = tempSum + buffer[i]; //total up readings
  }//end for

  //average sum
  output = tempSum/bufferSize;

  return(output);
}//end LPF function

/*
#####GET TEMP FLOAT DESCRIPTION#####  
This function converts a thermistor reading into a corresponding temp in ^C
The thermistor is incorporated into a Voltage Divider Circuit:

   +Vref---[Thermistor]---+--[1.8K]---GND
                          |
                         ADC @ thermPin

ADC Values were externally calculated from the calibration table using:           ADC = 1023*10000/(Rtherm+10000)
The LUT is an array of integer constants containing the predicted ADC         values for all temperatures between +6^C to +40.5^C.
The array index starts at zero, which corresponds to a temperature of         +6^C.
A linear interpolation between the two closest entries is performed to         give a finer output resolution.
*/

//##CONSTANTS##
/*1K8*/
const int LUT_Therm[] PROGMEM = //LUT containing ADC values
{
  223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C
  233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
  244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
  255, 256, 257, 258, 259, 260, 261, 263, 264, 265,
  266, 267, 268, 269, 271, 272, 273, 274, 275, 277,
  278, 279, 280, 281, 283, 284, 285, 286, 287, 289,
  290, 291, 292, 294, 295, 296, 297, 299, 300, 301,           //13^C to 13.9^C
  302, 304, 305, 306, 308, 309, 310, 312, 313, 314,
  315, 317, 318, 319, 321, 322, 323, 325, 326, 327,
  329, 330, 332, 333, 334, 336, 337, 338, 340, 341,
  343, 344, 345, 347, 348, 350, 351, 353, 354, 355,
  357, 358, 360, 361, 363, 364, 366, 367, 369, 370,
  371, 373, 374, 376, 377, 379, 380, 382, 383, 385,
  387, 388, 390, 391, 393, 394, 396, 397, 399, 400,
  402, 404, 405, 407, 408, 410, 411, 413, 415, 416,
  418, 419, 421, 423, 424, 426, 428, 429, 431, 433,
  434, 436, 438, 439, 441, 443, 444, 446, 448, 449,
  451, 453, 454, 456, 458, 460, 461, 463, 465, 466,
  468, 470, 472, 473, 475, 477, 479, 480, 482, 484,
  486, 488, 489, 491, 493, 495, 497, 498, 500, 502,
  504, 506, 507, 509, 511, 513, 515, 517, 519, 520,
  522, 524, 526, 528, 530, 532, 534, 535, 537, 539,
  541, 543, 545, 547, 549, 551, 553, 555, 557, 559,
  560, 562, 564, 566, 568, 570, 572, 574, 576, 578, 
  580, 582, 584, 586, 588, 590, 592, 594, 596, 598,
  600, 602, 604, 606, 608, 611, 613, 615, 617, 619,
  621, 623, 625, 627, 629, 631, 633, 635, 638, 640,
  642, 644, 646, 648, 650, 652, 655, 657, 659, 661,
  663, 665, 667, 670, 672, 674, 676, 678, 680, 683,
  685, 687, 689, 691, 694, 696, 698, 700, 702, 705,
  707, 709, 711, 714, 716, 718, 720, 723, 725, 727,
  729, 732, 734, 736, 738, 741, 743, 745, 747, 750, 
  752, 754, 757, 759, 761, 764, 766, 768, 771, 773,
  775, 778, 780, 782, 785, 787, 789, 792, 794, 796,
  799, 801, 803, 806, 808, 811, 813, 815, 818, 820,
  822, 825, 827, 830, 832, 834, 837, 839, 842, 844,
  847, 849, 851, 854, 856, 859, 861, 864, 866, 868,
  871, 873, 876, 878, 881, 883, 886, 888, 891, 893,
  896, 898, 901, 903, 906, 908, 911, 913, 916, 918, 
  921, 923, 926, 928, 931, 933, 936, 938, 941, 943,
  946, 948, 951, 953, 956, 958, 961, 963, 966, 969,
  971, 974, 976, 979, 981, 984, 987, 989, 992, 994,
  997, 999, 1002, 1005, 1007, 1010, 1012, 1015, 1017, 1020, //40^C to 49.9^C
  1023                                                     //50^C
};
const int constLUTArraySize = sizeof(LUT_Therm)/sizeof(LUT_Therm[0]);

float getTempFloat (int thermPin)
{
  //##VARIABLES##
  float _tempC; //intermediate results + final temperature return value
  int ADC_Lo; //the lower ADC matching value
  int ADC_Hi; //the higher ADC matching value
  float Temp_Lo; //the lower number matching temperature
  int mapTemp_Lo; //the lower number that will be entered into the map function
  float Temp_Hi; //the higher  number matching temperature
  int mapTemp_Hi; //the higher number that will be entered into the map function

  //prep ADC onto that particular analogue pin to sort out multiplexing etc
  analogRead(thermPin); 
  delay(10);
  //get raw ADC value from VDR
  int thermValue = analogRead(thermPin); 
  //Serial.println(thermValue);
  /*Serial.print( F("PinNo : ") );
  Serial.println(thermPin);*/
  Serial.print( F("ADC : ") );
  Serial.println(thermValue);

  //return dummy value if the sensor reading falls outside of the LUT
  if (thermValue < (int) pgm_read_word( &LUT_Therm[0] )) //less than the least ADC value
    _tempC = -errReturn-1; //under range dummy value

  else if (thermValue > (int) pgm_read_word(LUT_Therm[constLUTArraySize-1])) //more than the greatest ADC value
    _tempC = errReturn+1; //over range dummy value

  else //value falls in LUT range
  {
    int prev_lut_therm = 0;
    for (int i=0; i<constLUTArraySize; i++) //step through LUT and look for a match
    {    
      int lut_therm = (int) pgm_read_word(LUT_Therm[i]);
      if (lut_therm > thermValue) //LUT value is greater than the reading
      {  
        //find the closest higher ADC value
        ADC_Hi = lut_therm;
        //record the closest higher temperature        
        Temp_Hi = float(i/10) + 13.0; //convert to temp
        //get the closest lower temperature - taking the lower table boundary into account
        if (i != 0) //general case -> as long as it is not the first entry
        {
          ADC_Lo = prev_lut_therm; //store the previous array element as the low
          Temp_Lo = float(i/10) + 13.0 - 0.1; //convert to temp
        }
        else //special case -> counter = 0 ie first array entry
        {
          ADC_Lo = lut_therm; //store the first array element
          Temp_Lo = i - float(i/10) + 13.0; //convert to temp
        }//end if
        //interpolate the temperature value for greater precision
        //NB the map function does not use floating-point math, so the int values of temp are multiplied by 100 and then result is subsequently divided by 100
        mapTemp_Lo = Temp_Lo*100;
        mapTemp_Hi = Temp_Hi*100;
        _tempC = float(map(thermValue,ADC_Lo,ADC_Hi,mapTemp_Lo,mapTemp_Hi))/100;
        break;  //exit for loop after the match is detected
      }//end if
      prev_lut_therm = lut_therm;
    }//end for
  }//end if
  return(_tempC);
}//end getTempFloat function

Note the technique for declaring the LUT_Therm array, using the empty [] brackets (line 135).
That's followed by the const int array size (line 182) that is "calculated" from the array declaration: (Total array size) / (size of one array element).  If you ever change the lookup table, you don't have to count the elements by hand.  Let the compiler do it for you!  :)

[1] Although the IDE reports an increased binary sketch size, the total uploaded size is unchanged:


PROGMEM keyword   text    data     bss
No                5948     894     483
Yes               6810      32     483

As you can see, the 862 bytes for this table move from the data section to the text section.  The uploaded HEX files are identical at 93,737 bytes.

19548: <p>I've written a Arduino sketch that converts an analogue voltage to a temperature using a lookup table - code below. I've recently changed my LUT to include more values but ever since that my Serial monitor won't print out my debugging statements etc. So I limited the number of elements in the array and it was back to normal. But when I enter more debugging statements using the serial monitor, there is garbage before my statements (still readable though when I parse through it myself) or at the start nothing is printed.
I've checked that the two baud rates are the same but I just find it peculiar that if I take some of my println() statements out it runs okay. Tested everything else with a "Hello World" example but in the simple exaples the monitor works fine.</p>

<pre><code>    /*
    #####PROJECT DESCRIPTION##### 
    Measures temperature with an Arduino and NTC Thermistor (10Kohms @ 25^C)                                 in a voltage divider circuit
    Since the response is non-linear, a lookup table is used since there is a non linear response 
    The values in the LUT are the predicted values of the ADC at  temperature between 6^C and 40^C
    LUT has been derived from the calibration tests
    */
    //#####CONSTANTS#####
    const int constDelay = 3000; //constant delay for program 
    const int constNoOfAnaloguePins = 2; //number of analogue pins that are to be read
    const int errReturn = 998; //error value that is returned ***CHECK FOR CONSITENT VALUE ACROSS FUNCTIONS***
    //#####VARIABLE DECLARATIONS#####
    float avgTempC; //float var to store average of multiple temp readings

    //#####SETUP PROCEDURE#####
    void setup()
    {
      //this is the Setup part of your project - this is for code that is run only ONCE at startup
      for (int analoguePinCounter = 0; analoguePinCounter &lt; constNoOfAnaloguePins; analoguePinCounter++) //for loop to set up numerous analogue pins
      {
        pinMode(analoguePinCounter, INPUT);  //set pin mode of the analogue thermistor input
      }//end for
      analogReference(INTERNAL); //use the interval votlage of 1.1V for the ADC resolution
      Serial.begin(9600); //serial monitor baud rate
    }//end Setup function

    //#####LOOP PROCEDURE#####
    void loop()
    {
      //this is the main part of your project - put all continuously running code here
      for (int analoguePinCounter = 0; analoguePinCounter &lt; constNoOfAnaloguePins; analoguePinCounter++) //for loop to take temp readings from each analogue pin
      {
        //get LPF average reading over 25 samples
        avgTempC = LPF(analoguePinCounter, 25);
        //print out the readings
        if (avgTempC &lt; float(errReturn)) //there hasn't been any temps outside the range ***CHECK THE VALUE RETURNED FROM LPF IF ERROR***
        {
          Serial.print(analoguePinCounter);
          Serial.print(" | Average Temperature Readings = ");
          Serial.print(avgTempC, 2);
          Serial.println(" degC.");
          Serial.println("-------------------------");
        }
        else //avgTempC has returned X indicating an error
        {
          Serial.print(analoguePinCounter);
          Serial.println("**ERROR IN READING AVERAGE TEMP**");
          Serial.println("-------------------------");
          delay(10);
        }//end if
        delay(constDelay/2); //wait X/2 seconds until moving onto next sensor
      }//end for
      delay(constDelay); //wait X seconds until next loop
    }//end Loop function

    /*
    #####LOW PASS FILTER DESCRIPTION#####
    This function is a LPF for smoothing out signals or averaging
    It uses a static buffer to store the last "n" readings, and each time it is called,
    the oldest reading is discarded, the new reading is added, and the stack average
    value is returned.
    The buffer size is user-adjustable, but is constrained between 2 and 50
    An initialization function fills the entire buffer with the input value. 
    This is useful when the LPF function is called for the first time.
    Note: To meet the definition of a true LPF, this function must be called         at regular intervals.
    */
    //#####LOW PASS FILTER FUNCTION#####
    float LPF(int pinAnalogue, int bufferSize)
    {
      //##PRE PROCESSOR##
      #define bufferCap 75 //maximum buffer capacity
      //##CONSTANTS##
      const int constMAXERRORS = 5; //max number of error that can occur
      const int errReturn = 998; //value return if there is an error
      //##VARIABLES##
      float tempC; //var to store instantaneous temp
      static float buffer[bufferCap]; //array to act like a 'stack' of temp values ***DOES IT NEED TO BE STATIC NOW?***
      float tempSum; //to store the sum of the temperatures
      float output; //return value of LPF which is the average of the temp readings
      int errCounter = 0; //initialise error counter to 0

      //make sure buffer size is between the range
      bufferSize = constrain(bufferSize, 2, bufferCap);

      for (int i=0; i&lt;bufferSize; i++) //for loop to store temps in buffer array 
      {
        tempC = getTempFloat(pinAnalogue); //call function to get temperature from pin
        if ((tempC &gt; -errReturn) &amp;&amp; (tempC &lt; errReturn)) //no error 
        {
          buffer[i] = tempC; //store temp value into array
        }
        else //error
        {
          errCounter++; //increment counter for number of erroneous readings
          i--; //decrement counter as to not skip a sample index
          if (errCounter &gt; constMAXERRORS)
          {
            return(errReturn+1.0); //return the error value + 1
          }//end if
        }//end if
        delay(25); //allow the ADC to settle
      }//end for

      //calculate current stack average
      tempSum = 0; //initialise sum total
      for (int i=0; i&lt;bufferSize; i++) //go through stack array
      {
        tempSum = tempSum + buffer[i]; //total up readings
      }//end for

      //average sum
      output = tempSum/bufferSize;

      return(output);
    }//end LPF function

    /*
    #####GET TEMP FLOAT DESCRIPTION#####  
    This function converts a thermistor reading into a corresponding temp in ^C
    The thermistor is incorporated into a Voltage Divider Circuit:

       +Vref---[Thermistor]---+--[1.8K]---GND
                              |
                             ADC @ thermPin

    ADC Values were externally calculated from the calibration table using:           ADC = 1023*10000/(Rtherm+10000)
    The LUT is an array of integer constants containing the predicted ADC         values for all temperatures between +6^C to +40.5^C.
    The array index starts at zero, which corresponds to a temperature of         +6^C.
    A linear interpolation between the two closest entries is performed to         give a finer output resolution.
    */

    float getTempFloat (int thermPin)
    {
      //##CONSTANTS##
      /*1K8*/
      const int constLUTArraySize = 431;
      const int LUT_Therm[constLUTArraySize] = //LUT containing ADC values
      {
        223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C
        233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
        244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
        255, 256, 257, 258, 259, 260, 261, 263, 264, 265,
        266, 267, 268, 269, 271, 272, 273, 274, 275, 277,
        278, 279, 280, 281, 283, 284, 285, 286, 287, 289,
        290, 291, 292, 294, 295, 296, 297, 299, 300, 301,           //13^C to 13.9^C
        302, 304, 305, 306, 308, 309, 310, 312, 313, 314,
        315, 317, 318, 319, 321, 322, 323, 325, 326, 327,
        329, 330, 332, 333, 334, 336, 337, 338, 340, 341,
        343, 344, 345, 347, 348, 350, 351, 353, 354, 355,
        357, 358, 360, 361, 363, 364, 366, 367, 369, 370,
        371, 373, 374, 376, 377, 379, 380, 382, 383, 385,
        387, 388, 390, 391, 393, 394, 396, 397, 399, 400,
        402, 404, 405, 407, 408, 410, 411, 413, 415, 416,
        418, 419, 421, 423, 424, 426, 428, 429, 431, 433,
        434, 436, 438, 439, 441, 443, 444, 446, 448, 449,
        451, 453, 454, 456, 458, 460, 461, 463, 465, 466,
        468, 470, 472, 473, 475, 477, 479, 480, 482, 484,
        486, 488, 489, 491, 493, 495, 497, 498, 500, 502,
        504, 506, 507, 509, 511, 513, 515, 517, 519, 520,
        522, 524, 526, 528, 530, 532, 534, 535, 537, 539,
        541, 543, 545, 547, 549, 551, 553, 555, 557, 559,
        560, 562, 564, 566, 568, 570, 572, 574, 576, 578, 
        580, 582, 584, 586, 588, 590, 592, 594, 596, 598,
        600, 602, 604, 606, 608, 611, 613, 615, 617, 619,
        621, 623, 625, 627, 629, 631, 633, 635, 638, 640,
        642, 644, 646, 648, 650, 652, 655, 657, 659, 661,
        663, 665, 667, 670, 672, 674, 676, 678, 680, 683,
        685, 687, 689, 691, 694, 696, 698, 700, 702, 705,
        707, 709, 711, 714, 716, 718, 720, 723, 725, 727,
        729, 732, 734, 736, 738, 741, 743, 745, 747, 750, 
        752, 754, 757, 759, 761, 764, 766, 768, 771, 773,
        775, 778, 780, 782, 785, 787, 789, 792, 794, 796,
        799, 801, 803, 806, 808, 811, 813, 815, 818, 820,
        822, 825, 827, 830, 832, 834, 837, 839, 842, 844,
        847, 849, 851, 854, 856, 859, 861, 864, 866, 868,
        871, 873, 876, 878, 881, 883, 886, 888, 891, 893,
        896, 898, 901, 903, 906, 908, 911, 913, 916, 918, 
        921, 923, 926, 928, 931, 933, 936, 938, 941, 943,
        946, 948, 951, 953, 956, 958, 961, 963, 966, 969,
        971, 974, 976, 979, 981, 984, 987, 989, 992, 994,
        997, 999, 1002, 1005, 1007, 1010, 1012, 1015, 1017, 1020, //40^C to 49.9^C
        1023                                                     //50^C
      };
      const int errReturn = 998; //error value that is returned
      //##VARIABLES##
      float _tempC; //intermediate results + final temperature return value
      int ADC_Lo; //the lower ADC matching value
      int ADC_Hi; //the higher ADC matching value
      float Temp_Lo; //the lower number matching temperature
      int mapTemp_Lo; //the lower number that will be entered into the map function
      float Temp_Hi; //the higher  number matching temperature
      int mapTemp_Hi; //the higher number that will be entered into the map function

      //prep ADC onto that particular analogue pin to sort out multiplexing etc
      analogRead(thermPin); 
      delay(10);
      //get raw ADC value from VDR
      int thermValue = analogRead(thermPin); 
      //Serial.println(thermValue);
      /*Serial.print("PinNo : ");
      Serial.println(thermPin);*/
      Serial.print("ADC : ");
      Serial.println(thermValue);
      //return dummy value if the sensor reading falls outside of the LUT
      if (thermValue &lt; LUT_Therm[0]) //less than the least ADC value
        _tempC = -errReturn-1; //under range dummy value
      else if (thermValue &gt; LUT_Therm[constLUTArraySize-1]) //more than the greatest ADC value
        _tempC = errReturn+1; //over range dummy value
      else //value falls in LUT range
      {
        for (int i=0; i&lt;constLUTArraySize; i++) //step through LUT and look for a match
        {    
          if (LUT_Therm[i] &gt; thermValue) //LUT value is greater than the reading
          {  
            //find the closest higher ADC value
            ADC_Hi = LUT_Therm[i];
            //record the closest higher temperature        
            Temp_Hi = float(i/10) + 13.0; //convert to temp
            //get the closest lower temperature - taking the lower table boundary into account
            if (i != 0) //general case -&gt; as long as it is not the first entry
            {
              ADC_Lo = LUT_Therm[i-1]; //store the previous array element as the low
              Temp_Lo = float(i/10) + 13.0 - 0.1; //convert to temp
            }
            else //special case -&gt; counter = 0 ie first array entry
            {
              ADC_Lo = LUT_Therm[i]; //store the first array element
              Temp_Lo = i - float(i/10) + 13.0; //convert to temp
            }//end if
            //interpolate the temperature value for greater precision
            //NB the map function does not use floating-point math, so the int values of temp are multiplied by 100 and then result is subsequently divided by 100
            mapTemp_Lo = Temp_Lo*100;
            mapTemp_Hi = Temp_Hi*100;
            _tempC = float(map(thermValue,ADC_Lo,ADC_Hi,mapTemp_Lo,mapTemp_Hi))/100;
            break;  //exit for loop after the match is detected
          }//end if
        }//end for
      }//end if
      return(_tempC);
    }//end getTempFloat function
</code></pre>

<p>In this particular sketch no output is seen on the serial monitor. Has anyone come across this before or have any ideas how I could fix this?</p>
 7508: <p>I went through your program and found a few bugs you may want to fix. I
think only one of these (wastage of RAM) is really related to your
problem, but anyway, here it goes:</p>

<p>Fist, there are two issues with <code>LPF()</code>. The description states that
this is a rolling average low-pass filter. This is erroneous: a rolling
average would take a <em>single reading</em>, then report the average of the
last <em>n</em> readings. This function, in contrast, takes <em>n</em> readings and
reports their average. This makes a big difference: a rolling average
would need to store the last <em>n</em> values in static memory, while your
function does this for no good reason. You are just wasting
300&nbsp;bytes of RAM.</p>

<p>Here is a reimplementation of <code>LPF()</code> that does the same thing as yours
without wasting RAM. I changed its name to be more consistent with it's
real purpose:</p>



<pre class="lang-c++ prettyprint-override"><code>/*
 * Take 'count' temperature readings from 'pin' and return their average.
 * Returns NaN (not a number) if too many readings where in error.
 */
float getAvgTemp(int pin, int count)
{
  const int MAXERRORS = 5; // max number of errors that can occur
  float temp;              // current temperature reading
  float tempSum = 0;       // sum of temperatures
  int errCounter = 0;      // number of erroneous readings

  for (int i = 0; i &lt; count; i++) {

    // Try to get a valid reading.
    do {
      temp = getTempFloat(pin);
      if (isnan(temp))
        errCounter++;
      delay(25); // allow the ADC to settle
    } while (isnan(temp) &amp;&amp; errCounter &lt;= MAXERRORS);

    // Too many errors: return an error.
    if (errCounter &gt; MAXERRORS)
      return NAN;

    tempSum += temp;
  }

  return tempSum / count;
}
</code></pre>

<p>Here I use NaN (not a number) as an error indicator, as it is
semantically clearer than a random out-of-range value.</p>

<p>There are also a few errors in <code>getTempFloat()</code>:</p>

<ul>
<li><code>pgm_read_word(LUT_Therm[constLUTArraySize-1])</code> and
<code>pgm_read_word(LUT_Therm[i])</code> will not work: you have to pass
<code>pgm_read_word()</code> the <em>address</em> where to read.</li>
<li><code>float(i/10)</code> does not do what you want: it computes <code>i/10</code> as an
integer division (i.e. discarding the fractional part), and <em>then</em> it
converts the result to a float. If you want a floating point division,
you should make sure that at least one of the arguments is a float.
The usual idiom is <code>i/10.0</code>.</li>
</ul>

<p>Here is a version of <code>getTempFloat()</code> with these problems fixed, and
also somewhat simplified:</p>

<pre class="lang-c++ prettyprint-override"><code>float getTempFloat(int pin)
{
  int i, lutval, prev_lutval;

  // Take an analog reading.
  analogRead(pin);  // dummy reading to settle the MUX
  delay(10);
  int adc = analogRead(pin);
  Serial.print(F("ADC: "));
  Serial.println(adc);

  // Find i such that adc lies between LUT[i-1] and LUT[i].
  for (i = 0; i &lt; constLUTArraySize; i++) {
    prev_lutval = lutval;
    lutval = pgm_read_word(&amp;LUT_Therm[i]);
    if (lutval &gt;= adc) break;
  }

  // Special case: adc == LUT[0].
  if (i == 0 &amp;&amp; adc == lutval)
    return 13.0;

  // Report an error if out of range.
  if (i == 0 || i == constLUTArraySize)
    return NAN;

  // Return interpolated temperature.
  float fraction = float(adc - prev_lutval) / (lutval - prev_lutval);
  return 13.0 + (i-1 + fraction) / 10.0;
}
</code></pre>

<hr>

<h2>Addendum</h2>

<p>I have noticed a few more problems and inconsistencies with your
program.</p>

<h3>Powering the thermistor from the internal reference</h3>

<p>In <code>setup()</code>, you write</p>

<blockquote>
  <p>analogReference(INTERNAL); //use the interval votlage of 1.1V for the
  ADC resolution</p>
</blockquote>

<p>and then, in a comment further down you have the schematic</p>

<blockquote>
  <p>+Vref---[Thermistor]---+--[1.8K]---GND</p>
</blockquote>

<p>This suggests you are powering the voltage divider from the internal
voltage reference of the MCU. You should not do that, as the datasheet
states: “Note that V<sub>REF</sub> is a high impedance source, and only
a capacitive load should be connected in a system.”</p>

<h3>Relationship between ADC reading and thermistor resistance</h3>

<p>In the same comment as above, you wrote:</p>

<blockquote>
  <p>ADC = 1023*10000/(Rtherm+10000)</p>
</blockquote>

<p>Actually, the factor is 1024, not 1023. Again, see the datasheet. And
the number <code>10000</code> should be <code>1800</code>, i.e. the resistance you have put
between the ADC input and GND. I understand that you may have simply
changed the value and forgotten to update one of the comments. But you
should consider a misleading comment as a bug, especially if it's not
consistent with the actual code.</p>

<p>For this kind of measurement, you get the best precision if the pulldown
resistor has a value close to the resistance of the thermistor. The
comment at the beginning of the program says your thermistor has
10&nbsp;kΩ @&nbsp;25°C. This means that, if you are mostly interested in
the range around 25°C, a 10&nbsp;kΩ pulldown is better than 1.8&nbsp;kΩ.</p>

<h3>Relationship between array index and temperature</h3>

<p>The comment before the LUT says:</p>

<blockquote>
  <p>The array index starts at zero, which corresponds to a temperature of
  +6^C</p>
</blockquote>

<p>Then, the very first line of the LUT has the comment</p>

<blockquote>
  <p>//7^C to 7.9^C</p>
</blockquote>

<p>And later on, the implementation of <code>getTempFloat()</code> assumes
index 0 means 13°C. You should sort this out and make everything
consistent.</p>

<p>BTW, your LUT values go all the way up to 1023. A reading of 1023 would
mean the ADC voltage is higher than 1022.5/1024×V<sub>REF</sub>. Which
in turn would imply the thermistor has a resistance lower than
14.6&nbsp;Ω (assuming a 10&nbsp;kΩ pulldown). I find this dubious.</p>

<h3>Removal of the LUT</h3>

<p>Since your program is meant to run very slowly (<code>constDelay = 3000</code>),
you can afford doing complex computations in it. You can get the same
precision with a way smaller LUT if you use a higher order
interpolation. For a function sampled at constant steps, the
<a href="https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Interpolation_on_the_unit_interval_without_exact_derivatives" rel="nofollow">Catmull–Rom
spline</a>
is easy to implement and is way better than linear interpolation.</p>

<p>Or you can remove the LUT altogether and use an analytical expression
instead. If you derived the LUT from such an expression, why not use it
in the program? If the LUT derives from experimental data, you can try
to do an empirical fit, i.e. an arbitrary function that closely fits the
data. The most obvious (though maybe not the best) empirical function
would be a polynomial. Below is an example of such a function that
reproduces you LUT with good accuracy using a 6th degree polynomial. It
assumes the first LUT entry is for a temperature of 7°C:</p>

<pre class="lang-c++ prettyprint-override"><code>float getTempFloat(int pin)
{
    const float T0 = 7;   // temperature at beginning of range
    int adc = analogRead(pin);
    float x = (adc-223.) / (1023.-223.) * 2 - 1;  // scale to [-1:1]
    if (x &lt; -1 || x &gt; 1) return NAN;              // out of range
    float y = 1.474 - x*(0.533 - x*(0.732 - x*0.458));
    return T0 + 26.107 + x*(19.287 - x*(3.596 - x*y));
}
</code></pre>

<p>Actually this may be even more accurate than your LUT-based function, as
that LUT is made of integer values whereas the calibration curve should
obviously be continuous.</p>
 19409: <p>You have likely run out of RAM.</p>

<p>You have 431 integers in the look-up table alone. That equates to 862 bytes of SRAM. You also have a buffer of 75 floats, which equates to 300 bytes. This is in addition to all your other variables and function calls. </p>

<p>The Arduino Uno only has 2KB of SRAM.</p>

<p>Solutions:<br>
 1) Move your LUT to Flash (ie. program space) using the PROGMEM keyword (just before the equals sign):</p>

<pre><code>const int LUT_Therm[constLUTArraySize] PROGMEM = //LUT containing ADC values
</code></pre>

<p>2) Use an Arduino with a greater amount of SRAM. </p>

<ul>
<li>Arduino Mega  - 8KB SRAM  </li>
<li>Arduino ZERO  - 32KB SRAM  </li>
<li>Arduino Due   - 96KB SRAM  </li>
<li>Arduino MKR 1000/1010/1400/ZERO - 32KB SRAM</li>
</ul>
 14737: <p>Use the <code>F()</code> macro for all double-quoted strings you print.  Change lines like this:</p>

<pre><code>Serial.println(" degC.");
</code></pre>

<p>...to this:</p>

<pre><code>Serial.println( F(" degC.") );
</code></pre>

<p>This will save about 100 bytes of RAM.</p>

<p>And as BrettAM suggested, put that table into PROGMEM:</p>

<pre><code>  const int LUT_Therm[constLUTArraySize] PROGMEM = //LUT containing ADC values
  {
    223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C
</code></pre>

<p>This requires changing how you access the array, from this:</p>

<pre><code>  if (thermValue &lt; LUT_Therm[0]) //less than the least ADC value
</code></pre>

<p>...to this:</p>

<pre><code>  if (thermValue &lt; (int) pgm_read_word( &amp;LUT_Therm[0] )) //less than the least ADC value
</code></pre>

<p>Note the cast, the function call and the ampersand wrapped around the desired array element.  You must replace all uses of the array with this sequence.  You can also read it once into a local <code>int</code> and then use it normally:</p>

<pre><code>      int lut_therm = (int) pgm_read_word(LUT_Therm[i]); // read it in

      if (lut_therm &gt; thermValue) //LUT value is greater than the reading
</code></pre>

<p>This saves almost 1000 bytes of RAM!  The reported binary sketch size goes <em>up</em> by the same amount<sup>[1]</sup>.  </p>

<p>I had to pull the table out from inside <code>getTempFloat</code>, to the file scope.  Here's the complete sketch with those mods:</p>

<pre><code>/*
#####PROJECT DESCRIPTION##### 
Measures temperature with an Arduino and NTC Thermistor (10Kohms @ 25^C)                                 in a voltage divider circuit
Since the response is non-linear, a lookup table is used since there is a non linear response 
The values in the LUT are the predicted values of the ADC at  temperature between 6^C and 40^C
LUT has been derived from the calibration tests
*/

//#####CONSTANTS#####
const int constDelay = 3000; //constant delay for program 
const int constNoOfAnaloguePins = 2; //number of analogue pins that are to be read
const int errReturn = 998; //error value that is returned ***CHECK FOR CONSITENT VALUE ACROSS FUNCTIONS***

//#####VARIABLE DECLARATIONS#####
float avgTempC; //float var to store average of multiple temp readings

//#####SETUP PROCEDURE#####
void setup()
{
  //this is the Setup part of your project - this is for code that is run only ONCE at startup
  for (int analoguePinCounter = 0; analoguePinCounter &lt; constNoOfAnaloguePins; analoguePinCounter++) //for loop to set up numerous analogue pins
  {
    pinMode(analoguePinCounter, INPUT);  //set pin mode of the analogue thermistor input
  }//end for
  analogReference(INTERNAL); //use the interval votlage of 1.1V for the ADC resolution
  Serial.begin(9600); //serial monitor baud rate
}//end Setup function

//#####LOOP PROCEDURE#####
void loop()
{
  //this is the main part of your project - put all continuously running code here
  for (int analoguePinCounter = 0; analoguePinCounter &lt; constNoOfAnaloguePins; analoguePinCounter++) //for loop to take temp readings from each analogue pin
  {
    //get LPF average reading over 25 samples
    avgTempC = LPF(analoguePinCounter, 25);
    //print out the readings
    if (avgTempC &lt; float(errReturn)) //there hasn't been any temps outside the range ***CHECK THE VALUE RETURNED FROM LPF IF ERROR***
    {
      Serial.print(analoguePinCounter);
      Serial.print( F(" | Average Temperature Readings = ") );
      Serial.print(avgTempC, 2);
      Serial.println( F(" degC.") );
      Serial.println( F("-------------------------") );
    }
    else //avgTempC has returned X indicating an error
    {
      Serial.print(analoguePinCounter);
      Serial.println( F("**ERROR IN READING AVERAGE TEMP**") );
      Serial.println( F("-------------------------") );
      delay(10);
    }//end if
    delay(constDelay/2); //wait X/2 seconds until moving onto next sensor
  }//end for
  delay(constDelay); //wait X seconds until next loop
}//end Loop function

/*
#####LOW PASS FILTER DESCRIPTION#####
This function is a LPF for smoothing out signals or averaging
It uses a static buffer to store the last "n" readings, and each time it is called,
the oldest reading is discarded, the new reading is added, and the stack average
value is returned.
The buffer size is user-adjustable, but is constrained between 2 and 50
An initialization function fills the entire buffer with the input value. 
This is useful when the LPF function is called for the first time.
Note: To meet the definition of a true LPF, this function must be called         at regular intervals.
*/
//#####LOW PASS FILTER FUNCTION#####
float LPF(int pinAnalogue, int bufferSize)
{
  //##PRE PROCESSOR##
  #define bufferCap 75 //maximum buffer capacity
  //##CONSTANTS##
  const int constMAXERRORS = 5; //max number of error that can occur
  //##VARIABLES##
  float tempC; //var to store instantaneous temp
  static float buffer[bufferCap]; //array to act like a 'stack' of temp values ***DOES IT NEED TO BE STATIC NOW?***
  float tempSum; //to store the sum of the temperatures
  float output; //return value of LPF which is the average of the temp readings
  int errCounter = 0; //initialise error counter to 0

  //make sure buffer size is between the range
  bufferSize = constrain(bufferSize, 2, bufferCap);

  for (int i=0; i&lt;bufferSize; i++) //for loop to store temps in buffer array 
  {
    tempC = getTempFloat(pinAnalogue); //call function to get temperature from pin
    if ((tempC &gt; -errReturn) &amp;&amp; (tempC &lt; errReturn)) //no error 
    {
      buffer[i] = tempC; //store temp value into array
    }
    else //error
    {
      errCounter++; //increment counter for number of erroneous readings
      i--; //decrement counter as to not skip a sample index
      if (errCounter &gt; constMAXERRORS)
      {
        return(errReturn+1.0); //return the error value + 1
      }//end if
    }//end if
    delay(25); //allow the ADC to settle
  }//end for

  //calculate current stack average
  tempSum = 0; //initialise sum total
  for (int i=0; i&lt;bufferSize; i++) //go through stack array
  {
    tempSum = tempSum + buffer[i]; //total up readings
  }//end for

  //average sum
  output = tempSum/bufferSize;

  return(output);
}//end LPF function

/*
#####GET TEMP FLOAT DESCRIPTION#####  
This function converts a thermistor reading into a corresponding temp in ^C
The thermistor is incorporated into a Voltage Divider Circuit:

   +Vref---[Thermistor]---+--[1.8K]---GND
                          |
                         ADC @ thermPin

ADC Values were externally calculated from the calibration table using:           ADC = 1023*10000/(Rtherm+10000)
The LUT is an array of integer constants containing the predicted ADC         values for all temperatures between +6^C to +40.5^C.
The array index starts at zero, which corresponds to a temperature of         +6^C.
A linear interpolation between the two closest entries is performed to         give a finer output resolution.
*/

//##CONSTANTS##
/*1K8*/
const int LUT_Therm[] PROGMEM = //LUT containing ADC values
{
  223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C
  233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
  244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
  255, 256, 257, 258, 259, 260, 261, 263, 264, 265,
  266, 267, 268, 269, 271, 272, 273, 274, 275, 277,
  278, 279, 280, 281, 283, 284, 285, 286, 287, 289,
  290, 291, 292, 294, 295, 296, 297, 299, 300, 301,           //13^C to 13.9^C
  302, 304, 305, 306, 308, 309, 310, 312, 313, 314,
  315, 317, 318, 319, 321, 322, 323, 325, 326, 327,
  329, 330, 332, 333, 334, 336, 337, 338, 340, 341,
  343, 344, 345, 347, 348, 350, 351, 353, 354, 355,
  357, 358, 360, 361, 363, 364, 366, 367, 369, 370,
  371, 373, 374, 376, 377, 379, 380, 382, 383, 385,
  387, 388, 390, 391, 393, 394, 396, 397, 399, 400,
  402, 404, 405, 407, 408, 410, 411, 413, 415, 416,
  418, 419, 421, 423, 424, 426, 428, 429, 431, 433,
  434, 436, 438, 439, 441, 443, 444, 446, 448, 449,
  451, 453, 454, 456, 458, 460, 461, 463, 465, 466,
  468, 470, 472, 473, 475, 477, 479, 480, 482, 484,
  486, 488, 489, 491, 493, 495, 497, 498, 500, 502,
  504, 506, 507, 509, 511, 513, 515, 517, 519, 520,
  522, 524, 526, 528, 530, 532, 534, 535, 537, 539,
  541, 543, 545, 547, 549, 551, 553, 555, 557, 559,
  560, 562, 564, 566, 568, 570, 572, 574, 576, 578, 
  580, 582, 584, 586, 588, 590, 592, 594, 596, 598,
  600, 602, 604, 606, 608, 611, 613, 615, 617, 619,
  621, 623, 625, 627, 629, 631, 633, 635, 638, 640,
  642, 644, 646, 648, 650, 652, 655, 657, 659, 661,
  663, 665, 667, 670, 672, 674, 676, 678, 680, 683,
  685, 687, 689, 691, 694, 696, 698, 700, 702, 705,
  707, 709, 711, 714, 716, 718, 720, 723, 725, 727,
  729, 732, 734, 736, 738, 741, 743, 745, 747, 750, 
  752, 754, 757, 759, 761, 764, 766, 768, 771, 773,
  775, 778, 780, 782, 785, 787, 789, 792, 794, 796,
  799, 801, 803, 806, 808, 811, 813, 815, 818, 820,
  822, 825, 827, 830, 832, 834, 837, 839, 842, 844,
  847, 849, 851, 854, 856, 859, 861, 864, 866, 868,
  871, 873, 876, 878, 881, 883, 886, 888, 891, 893,
  896, 898, 901, 903, 906, 908, 911, 913, 916, 918, 
  921, 923, 926, 928, 931, 933, 936, 938, 941, 943,
  946, 948, 951, 953, 956, 958, 961, 963, 966, 969,
  971, 974, 976, 979, 981, 984, 987, 989, 992, 994,
  997, 999, 1002, 1005, 1007, 1010, 1012, 1015, 1017, 1020, //40^C to 49.9^C
  1023                                                     //50^C
};
const int constLUTArraySize = sizeof(LUT_Therm)/sizeof(LUT_Therm[0]);

float getTempFloat (int thermPin)
{
  //##VARIABLES##
  float _tempC; //intermediate results + final temperature return value
  int ADC_Lo; //the lower ADC matching value
  int ADC_Hi; //the higher ADC matching value
  float Temp_Lo; //the lower number matching temperature
  int mapTemp_Lo; //the lower number that will be entered into the map function
  float Temp_Hi; //the higher  number matching temperature
  int mapTemp_Hi; //the higher number that will be entered into the map function

  //prep ADC onto that particular analogue pin to sort out multiplexing etc
  analogRead(thermPin); 
  delay(10);
  //get raw ADC value from VDR
  int thermValue = analogRead(thermPin); 
  //Serial.println(thermValue);
  /*Serial.print( F("PinNo : ") );
  Serial.println(thermPin);*/
  Serial.print( F("ADC : ") );
  Serial.println(thermValue);

  //return dummy value if the sensor reading falls outside of the LUT
  if (thermValue &lt; (int) pgm_read_word( &amp;LUT_Therm[0] )) //less than the least ADC value
    _tempC = -errReturn-1; //under range dummy value

  else if (thermValue &gt; (int) pgm_read_word(LUT_Therm[constLUTArraySize-1])) //more than the greatest ADC value
    _tempC = errReturn+1; //over range dummy value

  else //value falls in LUT range
  {
    int prev_lut_therm = 0;
    for (int i=0; i&lt;constLUTArraySize; i++) //step through LUT and look for a match
    {    
      int lut_therm = (int) pgm_read_word(LUT_Therm[i]);
      if (lut_therm &gt; thermValue) //LUT value is greater than the reading
      {  
        //find the closest higher ADC value
        ADC_Hi = lut_therm;
        //record the closest higher temperature        
        Temp_Hi = float(i/10) + 13.0; //convert to temp
        //get the closest lower temperature - taking the lower table boundary into account
        if (i != 0) //general case -&gt; as long as it is not the first entry
        {
          ADC_Lo = prev_lut_therm; //store the previous array element as the low
          Temp_Lo = float(i/10) + 13.0 - 0.1; //convert to temp
        }
        else //special case -&gt; counter = 0 ie first array entry
        {
          ADC_Lo = lut_therm; //store the first array element
          Temp_Lo = i - float(i/10) + 13.0; //convert to temp
        }//end if
        //interpolate the temperature value for greater precision
        //NB the map function does not use floating-point math, so the int values of temp are multiplied by 100 and then result is subsequently divided by 100
        mapTemp_Lo = Temp_Lo*100;
        mapTemp_Hi = Temp_Hi*100;
        _tempC = float(map(thermValue,ADC_Lo,ADC_Hi,mapTemp_Lo,mapTemp_Hi))/100;
        break;  //exit for loop after the match is detected
      }//end if
      prev_lut_therm = lut_therm;
    }//end for
  }//end if
  return(_tempC);
}//end getTempFloat function
</code></pre>

<p>Note the technique for declaring the <code>LUT_Therm</code> array, using the empty <code>[]</code> brackets (line 135).</p>

<p>That's followed by the <code>const int</code> array size (line 182) that is "calculated" from the array declaration: (Total array size) / (size of one array element).  If you ever change the lookup table, you don't have to count the elements by hand.  Let the compiler do it for you!  :)
<hr>
[1] Although the IDE reports an increased binary sketch size, the total uploaded size is unchanged:</p>

<pre>
PROGMEM keyword   text    data     bss
No                5948     894     483
Yes               6810      32     483
</pre>

<p>As you can see, the 862 bytes for this table move from the <code>data</code> section to the <code>text</code> section.  The uploaded HEX files are identical at 93,737 bytes.</p>
