I was one of the lucky ones, and got in on the SparkFun "free day"; basically, they gave away $100 off of any order (with no minimum, so you could literally just order $100 of stuff) to anyone lucky enough to be able to submit an order during the ordering period, which was pretty tricky given how badly their servers melted under the load. :-)
Anyway, one of the things I picked up was an Arduino starter kit; an Arduino Duemilanove (the guts of the system), along with a bunch of small sensors, LEDs, and other widgets to help you build stuff with it. Learning a new toy like this always requires that I give myself a real project to tackle with it; if I don't actually "scratch an itch" with it, it ends up getting relegated to "cute toy" status pretty quickly.
As luck would have it, a project presents itself: my wife hates our "programmable" (and I use the term loosely) thermostat, and I'm not prepared to pay a king's ransom for what is basically a small microcontroller and about $15 in parts. So, tonight's project was diving into reading a simple 10K thermistor, and producing some kind of useful output. Turns out, it was much easier than expected. I borrowed a bit of code from both a tri-color LED example, and some example thermistor code, and produced the following sketch that displays green when the temperature is comfortable (by my definition, anyway), red when it's hot, blue when it's cold, and gradiants in-between leading up to the extremes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | // Fading LED colors based on temperature.
// Ed Marshall <esm@logic.net>
#include <math.h>
int redPin = 9; // Red LED, connected to digital pin 9
int greenPin = 10; // Green LED, connected to digital pin 10
int bluePin = 11; // Blue LED, connected to digital pin 11
int wait = 50; // 50ms (.05 second) delay; shorten for faster fades
int DEBUG = 0; // DEBUG counter; if set to 1, will write values back via serial
void printDouble(double val, byte precision) {
// prints val with number of decimal places determine by precision
// precision is a number from 0 to 6 indicating the desired decimal places
// example: printDouble(3.1415, 2); // prints 3.14 (two decimal places)
Serial.print (int(val)); //prints the int part
if( precision > 0) {
Serial.print("."); // print the decimal point
unsigned long frac, mult = 1;
byte padding = precision -1;
while(precision--) mult *=10;
if(val >= 0) frac = (val - int(val)) * mult; else frac = (int(val) - val) * mult;
unsigned long frac1 = frac;
while(frac1 /= 10) padding--;
while(padding--) Serial.print("0");
Serial.print(frac,DEC) ;
}
}
double Thermistor(int RawADC) {
// Inputs ADC Value from Thermistor and outputs Temperature in Celsius
// requires: include <math.h>
// Utilizes the Steinhart-Hart Thermistor Equation:
// Temperature in Kelvin = 1 / {A + B[ln(R)] + C[ln(R)]^3}
// where A = 0.001129148, B = 0.000234125 and C = 8.76741E-08
long Resistance; double Temp; // Dual-Purpose variable to save space.
Resistance=((10240000/RawADC) - 10000); // Assuming a 10k Thermistor. Calculation is actually: Resistance = (1024/ADC)
Temp = log(Resistance); // Saving the Log(resistance) so not to calculate it 4 times later. // "Temp" means "Temporary" on this line.
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp)); // Now it means both "Temporary" and "Temperature"
Temp = Temp - 273.15; // Convert Kelvin to Celsius // Now it only means "Temperature"
return Temp;
}
void setup()
{
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
if (DEBUG) { // If we want to see the pin values for debugging...
Serial.begin(9600); // ...set up the serial ouput on 0004 style
}
}
void loop() {
double Temp;
double TempCalc;
int TempScaled, RedLED, GreenLED, BlueLED;
Temp = Thermistor(analogRead(0));
// We'll say that 15C - 30C is our "comfortable" range.
// < 15 is very cold (solid blue), > 30 is very hot (solid red).
TempCalc = (Temp - 15) / 15;
if (TempCalc < 0) {
TempCalc = 0;
} else if (TempCalc > 1) {
TempCalc = 1;
}
TempScaled = (TempCalc * 512) - 1;
if (TempScaled > 255) {
TempScaled -= 256;
BlueLED = 0;
GreenLED = 255 - TempScaled;
RedLED = TempScaled;
} else {
BlueLED = 255 - TempScaled;
GreenLED = TempScaled;
RedLED = 0;
}
if (DEBUG) {
DEBUG += 1;
// Only perform debugging output every 10 loop iterations.
if (DEBUG > 10) {
DEBUG = 1;
Serial.print("Temperature: ");
printDouble(Temp, 3);
Serial.println("C");
Serial.print("Red: ");
Serial.print(RedLED);
Serial.print("\tGreen: ");
Serial.print(GreenLED);
Serial.print("\tBlue: ");
Serial.println(BlueLED);
Serial.println();
}
}
analogWrite(redPin, RedLED);
analogWrite(greenPin, GreenLED);
analogWrite(bluePin, BlueLED);
delay(wait);
}
|