Thermocouple referencing for LED outputs

Hi, I have been messing around with a thermocouple lately, using it to read temperatures and output the readings in Fahrenheit to a small lcd screen. I am now trying to use the thermocouple’s readings to power different LEDs based on the temp it reads. For example, when the thermocouple reads temperatures >= 72.22 degrees, it powers a blue LED. When the temp is <= 72.21 degrees, the LED is powered off. An example of my “if” statement to determine what to do with the LED:

lcd.print("Temp = ");
lcd.println(farenheit);
}
if ((farenheit) >= ‘72.22’)
{
digitalWrite (led,HIGH);
}
else ((farenheit) <= ‘72.21’);
{
digitalWrite (led,LOW);
}

(“farenheit” (spelled wrong, I know) was previously defined in the program)
When I run this program through the arduino, the LED never powers on. I am monitoring the temperatures via serial connection and on the lcd screen. I think I am referencing the reading incorrectly? Any help would be greatly appreciated. Thanks

It looks like a farenheit is a string (text) instead of a float.

Somewhere in the code, there should be a numerical value (perhaps the actual ADC reading) that you can compare. Or you can convert the string to a float, but I've forgotten the function to do that so you'd have to look it up.

You also don't need any additional conditions associated with the else condition... A simple else will do.

I thought about that, however I do not get any errors when compiling the code. I tried using atof(), and I get an "invalid conversion from 'int' to 'const char*'. This leads me to believe that farenheit is already an integer.

My color LED vs temp:
Hot Yet?

Ray

/* 
   M. Ray Burnette 20140210 Open Source: for "Hot Yet?" publication
   Coding Badly Tiny core: https://code.google.com/p/arduino-tiny/
   Binary sketch size: 2,852 bytes (of a 8,192 byte maximum)
   Arduino 1.0.5 No bootloader used.  Upload via ISP.
   Project 3.3V Attiny85 @8MHz internal,  under 10mA idle at 68F

   Schematic:
   x-----------------/\/\/\/\/\/\/\/---------------x---/\/\/\/\/\/\/\----xGND
   |                NTC 10K Thermistor             |  10K 1% Resistor
   |                                               |
   |              ATTINY85 / ARDUINO               |
   |                     +-\/-+                    |
   |    Ain0 (D 5) PB5  1|    |8  Vcc              |
   x--- Ain3 (D 3) PB3  2|    |7  PB2 (D 2) Ain1 --- 
(Blue)- Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1  (Green) ----------|<---x
   |               GND  4|    |5  PB0 (D 0) pwm0  (Red) ------------|<---x
   |                     +----+                                          |    100 Ohm
   x----------------------------------------------------------------|<---x---/\/\/\/\/---Vcc 3.3V

*/
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

boolean flag_wdt = 1;

int pinT = PB3;           // Thermistor source voltage
int pinR = PB0;           // Digital pin #0  Red
int pinG = PB1;           // Digital pin #1  Green
int pinB = PB4;           // Digital pin #4  Blue
int r; int g; int b;
const int nToSleep = 50 ; // # of stable temp readings before sleep
const int Delay =    100; // main loop delay in mS
double ADCcount;
double ADCprevious;
int nCount;
int ThermistorPin  = 1 ;  // A1 is physical pin #7 (PB2)

void setup()
{
  // WDTO_15MS, WDTO_30MS, WDTO_60MS, WDTO_120MS, WDTO_250MS, WDTO_500MS, 
  // WDTO_1S, WDTO_2S, WDTO_4S, WDTO_8S
  setup_watchdog(WDTO_4S);  // Periodic Heartbeat to awaken deep sleep()
  sleep_disable();
  pinMode(pinT, OUTPUT); digitalWrite(pinT, HIGH);  // Thermistor Source
  pinMode(pinR, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(pinB, OUTPUT);
}
  
void loop() 
{
  wdt_reset();    // pat K9
  ADCcount = analogRead(ThermistorPin) ;
  if (ADCcount == ADCprevious) ++nCount;
  if ( nCount > nToSleep )
  { // prepare for low current power-down state
    pinMode(pinR, INPUT); digitalWrite(pinR, HIGH);  // pullup enabled
    pinMode(pinG, INPUT); digitalWrite(pinG, HIGH);
    pinMode(pinB, INPUT); digitalWrite(pinB, HIGH);
    SleepLonger:    // Come here to re-sleep
    pinMode(pinT, INPUT); digitalWrite(pinT, HIGH);
      system_sleep();
      sleep_disable();  // deep sleep until WDT kicks
      pinMode(pinT, OUTPUT); digitalWrite(pinT, HIGH);
      delay(50);
      // Yawn, exercise a few reads for stabilization
      for (uint8_t z=0; z<5; z++) {
        ADCcount = analogRead(ThermistorPin) ;
      }
      if (abs(ADCcount - ADCprevious) < 4) goto SleepLonger;  // hysteresis
    // restore LED output drivers ... temp has gone up
    pinMode(pinR, OUTPUT); digitalWrite(pinR, HIGH);
    pinMode(pinG, OUTPUT); digitalWrite(pinG, HIGH);
    pinMode(pinB, OUTPUT); digitalWrite(pinB, HIGH);
    nCount = 0;
  } else {
  // 261 = 32F, 447 = 64F, 537 = 75F, 575 = 82F
  b = map(ADCcount, 261,  447, 100, 255 );
  g = map(ADCcount, 435,  574, 250, 100);  // overlap green & blue
  r = map(ADCcount, 575, 1023, 250,  50);

  if (ADCcount > 574)              // HOT: ADCcount goes up with increase temperature
    {
      // Show only Red when Hot with Red intensity increasing with temperature
      analogWrite(pinR,   r);
      analogWrite(pinG, 255);      // 255 = 100% High == NO LED Current Common Anode --> Vcc
      analogWrite(pinB, 255);      // Blue Off
    } else {                       // Cold to Cool transition with Blue fading into Green
      analogWrite(pinR, 255);      // Red Off
      analogWrite(pinG, g);
      analogWrite(pinB, b);        // Brighter Blue with colder temp
    }
  }
  ADCprevious = ADCcount;
  delay(Delay);
}

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
// http://www.insidegadgets.com/wp-content/uploads/2011/02/ATtiny85_watchdog_example.zip
void system_sleep()
{
    cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF
    power_all_disable ();                // power off ADC, Timer 0 and 1, serial interface
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
    noInterrupts ();                     // timed sequence coming up
    sleep_enable();
    interrupts ();                       // interrupts are required now
    sleep_mode();                        // System sleeps here
    sleep_disable();                     // System continues execution here when watchdog timed out
    power_all_enable ();                 // power everything back on
    sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
}

// 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii)
{
  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;

  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCR = bb;
  WDTCR |= _BV(WDIE);
}
  
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
     // wdt_disable();  // disable watchdog
}

mrburnette, could you briefly explain the idea behind the program? I am relatively new to programming, and I am trying to figure it all out!

Read ADC 5 times to get an average (as a sum)

for (uint8_t z=0; z<5; z++) {
        ADCcount = analogRead(ThermistorPin) ;

If the temp did not change much, sleep longer

 if (abs(ADCcount - ADCprevious) < 4) goto SleepLonger;

Get a blended color… Blue= cool, Red= hot

// 261 = 32F, 447 = 64F, 537 = 75F, 575 = 82F
  b = map(ADCcount, 261,  447, 100, 255 );
  g = map(ADCcount, 435,  574, 250, 100);  // overlap green & blue
  r = map(ADCcount, 575, 1023, 250,  50);

Now, if hot, only show the Red, or show Blue+Green blend…

 if (ADCcount > 574)              // HOT: ADCcount goes up with increase temperature
    {
      // Show only Red when Hot with Red intensity increasing with temperature
      analogWrite(pinR,   r);
      analogWrite(pinG, 255);      // 255 = 100% High == NO LED Current Common Anode --> Vcc
      analogWrite(pinB, 255);      // Blue Off
    } else {                       // Cold to Cool transition with Blue fading into Green
      analogWrite(pinR, 255);      // Red Off
      analogWrite(pinG, g);
      analogWrite(pinB, b);        // Brighter Blue with colder temp
    }

Most everything else is low power sleep and watch-dog wake

I am sorry, I'm still not following you. Currently my thermocouple's breakout board sends data out (DO) to the Digital pin 6 on my arduino. How can I come up with analog values when I am using a digital pin? I tried switching the DO pin over to analog pin 4, and using analogRead to display the value in my serial monitor, but that shows a near constant value, even when the thermocouple is placed in cold water and is held above a flame.

Aaaaaand I just realized the whole time, the power pin to the breakout board was unplugged.

Still having problems though. I had figured that I could somehow read the voltage the breakout board was outputting (which confuses me, since it outputs to a digital pin, not an analog pin, and works that way), then map the voltages to corresponding serial outputs 0-1023, then map that value to temperature values, and use that as the reference for the LED

Hi,
Can you please post a copy of your sketch, using code tags.
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

lcd.print("Temp = ");
    lcd.println(farenheit);
  }
   if (farenheit >= 72.22);
   {
    digitalWrite (led,HIGH);
   }
 else if (farenheit <= 72.21);
  {
    digitalWrite (led,LOW);
  }

These changes may help.

Tom… :slight_smile:

#include <LiquidCrystal.h>

// Connections:
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
#include <SPI.h>
#include “Adafruit_MAX31855.h”
#include <LiquidCrystal.h>
#define DO 6
#define CS 8
#define CLK 9
Adafruit_MAX31855 thermocouple(CLK, CS, DO);
int led = 13; // pin 13 will control the backlight
int potpin = 1; // jumper potpin to LCD and to analog pin #0
int ledpin = 7;
int potpin2 = 0;
int val = A1;
int analogval = 0;
int c = thermocouple.readCelsius();
int farenheit = ((c *9)/5+32);

void setup()
{
Serial.begin (9600);

pinMode(led, OUTPUT);

lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.print(“Temp Farenheit”);
delay(500);
pinMode(val, INPUT);

}

void loop() {
analogval = analogRead(val);
Serial.println(analogval);
lcd.setCursor(0, 0);
double c = thermocouple.readCelsius();
lcd.setCursor(0,1);
if (isnan(c))
{
lcd.print(‘T/C Problem’);
}
else
{
int farenheit = ((c *9)/5+32);
lcd.print("Temp = ");
lcd.println(farenheit);
}
if (farenheit >= ‘72.22’)
{
digitalWrite (led,HIGH);
}
else if (farenheit <= 72.21);
{
digitalWrite (led,LOW);
}
delay(1000);
}

I'll include a picture of the circuit later, when I get a chance to draw it out!

Hi, almost got it all, still some inverted commas to take out.

lcd.print("Temp = ");
    lcd.println(farenheit);
  }
   if (farenheit >= 72.22);
   {
    digitalWrite (led,HIGH);
   }
 else if (farenheit <= 72.21);
  {
    digitalWrite (led,LOW);
  }

Tom… :slight_smile:

From reply #5

Read ADC 5 times to get an average (as a sum)
Code: [Select]
for (uint8_t z=0; z<5; z++) {
ADCcount = analogRead(ThermistorPin) ;

The explanation doesn’t match the code, it seems to me.

If you want to chuck away readings, and make it plain to the reader that that is what is intended, then (void)analogRead(ThermistorPin); would seem to me to be clearer.