Controlling LED's with a Thermistor

I am trying to get a "bodged" LED array to light up depending on the value of a thermistor, so the LED's from green to red would be 19 to 25 celsius for example.

I have 1 blue, 2 green, 2 yellow and 2 red LED's, in that order, but don't know how I would wire them up to do what I want to do.

With what I want to do, think of a digital temperature gage, too low and the blue LED glows, 19C and the first green, 20 and the first 2, 22 and the first 3, 23 and the first 4, 25 and the first 5 will glow, anything more than that and the last red glows.

In the array, the blue is ONLY used to display when too cold.

I know that connecting a 220 ohm resistor through the 5v will make an LED glow, but have no idea how to actually control when it is on or not.

You could ask Google. There are tons of tutorials on Arduino and LEDs

KyleBriggs: I know that connecting a 220 ohm resistor through the 5v will make an LED glow, but have no idea how to actually control when it is on or not.

By connecting it to an output pin, instead of 5V. Still with the resistor!

Update:

I decided to start connecting them all up to the digital pins for use, and added all the veriables to a very messy state machine to check the range, but I am getting loads of errors about the use of the “<” symbol, which is of course needed to check the range.

#include <math.h>         //loads the more advanced math functions
 
void setup() {            //This function gets called when the Arduino starts
  Serial.begin(9600);   //This code sets up the Serial port at 115200 baud rate
}
 
double Thermister(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;              // Convert Kelvin to Celsius
 //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
 return Temp;
}
 
void loop() {             //This function loops while the arduino is powered
  int val;                //Create an integer variable
  double temp;            //Variable to hold a temperature value
  val=analogRead(0);      //Read the analog port 0 and store the value in val
  temp=Thermister(val);   //Runs the fancy math on the raw analog value
  Serial.println(temp);   //Print the value to the serial port
  delay(1000);            //Wait one second before we do it again

  if(temp < 19)
  {
    digitalWrite(2, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >= 19 && < 20)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >=20 && < 21)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >=21 && < 22)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >=22 && < 23)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >=23 && < 24)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(8, LOW);
  }
  if(temp >=24)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(8, HIGH);
  }
}
if(temp >= 19 && < 20)

If what is less than 20? temp? There are no compound comparisons in C/C++.

if(temp >= 19 && < 20)
if(temp >= 19 && temp < 20)

Or

if(temp == 19)

;)

aarg:
Or

if(temp == 19)

:wink:

temp in his code is a double. It could be 19.5 and still trip that if.

After changing my code to the below, my output now displays as “nan”.

#include <math.h>         //loads the more advanced math functions
 
void setup() {            //This function gets called when the Arduino starts
  Serial.begin(9600);   //This code sets up the Serial port at 115200 baud rate
}
 
double Thermister(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;              // Convert Kelvin to Celsius
 //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
 return Temp;
}
 
void loop() {             //This function loops while the arduino is powered
  int val;                //Create an integer variable
  double temp;            //Variable to hold a temperature value
  val=analogRead(0);      //Read the analog port 0 and store the value in val
  temp=Thermister(val);   //Runs the fancy math on the raw analog value
  Serial.println(temp);   //Print the value to the serial port
  delay(1000);            //Wait one second before we do it again

  if(temp < 19)
  {
    digitalWrite(2, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >= 19 && temp < 20)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >=20 && temp < 21)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >=21 && temp < 22)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >=22 && temp < 23)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
  if(temp >=23 && temp < 24)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(8, LOW);
  }
  if(temp >=24)
  {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(8, HIGH);
  }
}

nan means Not A Number. That means you've done something impossible in the math somewhere like dividing by zero or trying to take the log of a negative number.

Have the program print out the raw values and run them through the math yourself on paper and see if you can spot the problem.

Two things to keep in mind:

log really means natural logarithm. In math we usually write ln. But on Arduino it's log. log base ten like we usually mean in math when we write log is log10.

Secondly this calculation:

10240000/RawADC

will be done with integer math. If you want a floating point number out of that you should make one of the numbers a float like this.

10240000.0/RawADC

Delta_G:
temp in his code is a double. It could be 19.5 and still trip that if.

Ah. Missed that. But then comparing to <23 and later >=23 is not a good idea because of the inexact nature of floating point. This should be done with “nested bounds”.

aarg:
Ah. Missed that. But then comparing to <23 and later >=23 is not a good idea because of the inexact nature of floating point. This should be done with “nested bounds”.

Explain?

I know you can’t use exactly equals with floats, but it seems like whatever number you get exact or not is either less than 23 or greater or equal to 23. As long as you don’t take a new reading in between.

Delta_G: Explain?

I know you can't use exactly equals with floats, but it seems like whatever number you get exact or not is either less than 23 or greater or equal to 23. As long as you don't take a new reading in between.

This was what I thought.

Delta_G: nan means Not A Number. That means you've done something impossible in the math somewhere like dividing by zero or trying to take the log of a negative number.

Have the program print out the raw values and run them through the math yourself on paper and see if you can spot the problem.

Two things to keep in mind:

log really means natural logarithm. In math we usually write ln. But on Arduino it's log. log base ten like we usually mean in math when we write log is log10.

Secondly this calculation:

10240000/RawADC

will be done with integer math. If you want a floating point number out of that you should make one of the numbers a float like this.

10240000.0/RawADC

I haven't touched the math side of things since adding in the LED's and it worked before then so I'm not sure what happened there.

As far as the calculation goes, when I added the ".0" decimal onto the end, I no longer get "nan" as a result, but minus results.

I am getting a pretty consistent "-273.15", if I heat up the thermistor, after a while it stops sending the warmer result and defaults back to -273.15, so I'm not really sure what's going on at the moment.

How have you got the thing wired up? Can you draw us a quick schematic? The -273.15 number is telling because that's absolute zero. It would mean your calculations are coming out to zero.

I still think it would be worthwhile to look at the raw values and see if they make sense through the math on paper.

Can you link to where you got that formula? Are you sure you should be using the natural logarithm and not the base 10 log? If the formula says ln, then you use log in code. If the formula says log you use log10 in code.

I ran the code in the latest post, and it runs perfectly for me. I would be checking your connections.

I did not do anything with leds and conditional tests, just read the temperature.

Delta_G:
Explain?

I know you can’t use exactly equals with floats, but it seems like whatever number you get exact or not is either less than 23 or greater or equal to 23. As long as you don’t take a new reading in between.

I see. But look at all the redundant testing. If the first test passes, all the subsequent tests are still performed. That’s horribly inefficient. Also, when you maintain the code, every time you change a value, you have to change two lines. That’s a chance for errors to creep in. The better structure I was referring to is the following. See if you don’t agree.

if (temp<19) ...
else if (temp <20) ...
else if (temp <21) ...
else if (temp <22) ...

Oh absolutely. I see where you’re going. I thought you were implying that there was a number not less than, equal to, or greater than 23.

Delta_G: Oh absolutely. I see where you're going. I thought you were implying that there was a number not less than, equal to, or greater than 23.

Ha ha. Of course not. But there might be some funny business about the way the library code handles conversions and comparisons (and I do say might). My complaint is not about the number, but the way it is tested. A comparison for equality might be using a different algorithm than one comparing for inequality. With integers the result of both must be the same by definition, but there is no such implicit guarantee with float. No doubt it can be verified by studying the library code (or dismissed as improbable), but not as reliably as avoiding the problem entirely by using nested ranges, and gaining speed, clarity and maintainability in the bargain.

Delta_G:
How have you got the thing wired up? Can you draw us a quick schematic? The -273.15 number is telling because that’s absolute zero. It would mean your calculations are coming out to zero.

I still think it would be worthwhile to look at the raw values and see if they make sense through the math on paper.

Can you link to where you got that formula? Are you sure you should be using the natural logarithm and not the base 10 log? If the formula says ln, then you use log in code. If the formula says log you use log10 in code.

I hava attached an image of my setup, with a quickly built board design in Fritzing.

To read that thermistor shouldn't you have power to one side and the resistor going to ground to the other side and take the reading in between? Right now there's no source of voltage anywhere you've just got two resistors (the actual resistor and the thermistor) connected to ground. So the raw value you read on A0 will always be 0. How could it ever be anything else?