Best way to set up a button to toggle a second function? (millis issue now)

Hello all, I have a temperature sensor device that I want add datalogging too, and finally grabbed some SD card boards.

Now, this is the code as follows, it interfaces with the dallas instruments one wire temperature sensors. It continuously reads out the temperature, and when the temperature stabilizes, it turns on an LED to indicate this, and when the temperature shifts, it turns it off.

#include <OneWire.h>
#include <LiquidCrystal.h>

OneWire  ds(10);
LiquidCrystal lcd(6, 7, 5, 4, 3, 2);
float lasttemp;                        //Variable for last temperature
float delta;                           //Variable for temperaturechange
long previousMillis = 0;
long interval = 20000;                 //Check once every 20 seconds

void setup(void) {
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  lcd.begin(8, 2);
  lcd.setCursor(0,0);
  lcd.print("STARTING");
  lcd.setCursor(0, 1);
  lcd.print("VER. 1.1");
  delay(1000);
  lcd.clear();
}

  
void loop(void) {
  unsigned long currentMillis = millis();
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;

  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
  }
  Serial.println();

  // the first ROM byte indicates which chip
  switch (addr[0]) {
  case 0x10:
    Serial.println("  Chip = DS18S20");  // or old DS1820
    type_s = 1;
    break;
  case 0x28:
    Serial.println("  Chip = DS18B20");
    type_s = 0;
    break;
  case 0x22:
    Serial.println("  Chip = DS1822");
    type_s = 0;
    break;
  default:
    Serial.println("Device is not a DS18x20 family device.");
    return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } 
  else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }

  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");

  delta = celsius - lasttemp;                       //Create value to check how much temperature has changed

  if (currentMillis - previousMillis > interval) {  //If it has been 20 seconds, check to turn LED on
    previousMillis = currentMillis;
    if ((delta < 00.03) && (delta > -00.03)) {      //If temperature hasn't changed by +/- .05 turn led on.
      digitalWrite(13, HIGH); 
    }
  }
  if (delta >= 00.06) {                             //If temperature has changed by more than .1 turn LED off
    digitalWrite(13, LOW);
  }
  if (delta <= -00.06) {
    digitalWrite(13, LOW);                         // If temperature has changed by more than -.1 turn LED off
  }

  lcd.setCursor(0, 0);
  lcd.print(celsius);
  lcd.print(" C ");
  lcd.setCursor(0, 1);
  lcd.print(fahrenheit);
  lcd.print(" F ");
  lasttemp = celsius;

}

Now, I want to maintain this functionality, but also add in a button to toggle SD card logging, which will write to the sd card every x milliseconds (not sure on the length of time I want right now, probably every 5 seconds or so).

I'm wondering what the best way to implement this is, I don't want to add any delays to the temperature readout, and certainly don't want to have it update once every 5 seconds. I think you need a timeout to make sure the button press doesn't repeat though, correct?

It's been a while so I can't recall how to set up smaller sections that you can run once (not in the main loop as an if/else statement, but in one which will run once).

I also saw multipleblinks, and it seems that some arduinos can run multiple loops at once now? I'm not sure if that works for all, or if a pro mini would be capable of this.

Anyways, I can handle the sd card writing and delay, all that stuff, I'm just a bit stuck on how to basically be able to press the button at any time to start/stop datalogging.

Alright, I'll have to poke through those, the example uses a momentary which is good, that's where I figured the biggest issue would be.

I first need to find a decent way to cut a slot for the SD card though, and not have it be butt ugly.

Delta_G:
There's nothing special about the fact that example toggles an LED, it could be doing anything at regular intervals.

In fact, I think it's a big pity that the two most common examples, Blink (with delay) and BlinkWithOutDelay, use LEDs at all. It tends to give the impression that Arduinos are toys and wow, can blink these lights, but don't try anything serious with them.

The approaches in BlinkWithOutDelay and the state change example (which also turns a light off and on) are, to me, the most important Arduino concepts.

JimboZA:
In fact, I think it's a big pity that the two most common examples, Blink (with delay) and BlinkWithOutDelay, use LEDs at all. It tends to give the impression that Arduinos are toys and wow, can blink these lights, but don't try anything serious with them.

The approaches in BlinkWithOutDelay and the state change example (which also turns a light off and on) are, to me, the most important Arduino concepts.

Yeah, I haven't needed anything like this before, but for interactivity it seems like they would be pretty key. I would also like if they just triggered a more generic if/else statement or something.

Well I suppose the point is, that there's nothing more generic than an LED going on or off, and if the timing's right that could just as easily be firing retro rockets to land on Mars.

But if you embrace those two approaches, you're good to do just about anything.

Those and the idea of using a flag to check if something needs doing or not, as explained by PaulS thusly:

bool beenThereDoneThat = false;

if(!beenThereDoneThat)
{
    GoThereDoThat();
    beenThereDoneThat = true;
}

JimboZA:
In fact, I think it's a big pity that the two most common examples, Blink (with delay) and BlinkWithOutDelay, use LEDs at all. It tends to give the impression that Arduinos are toys and wow, can blink these lights, but don't try anything serious with them.

Without any additional hardware it's the only thing the Arduino can do to demonstrate. One could have used the Serial Monitor instead of the LED; would that have been better?

God, it's getting cramped in this thing, it was a lapell mic case and it was plenty roomy until now. I wish I had known back when I made this that analog pins can be used the same as digital, although maybe they wouldn't work for the lcd, not sure, but with that cable going over the arduino, it sure is tricky to get my iron in there.

I just need to add the switch, an LED to shine through the hole on the SD card to indicate logging, and then close it up, hopefully never to open it again lol. I'm going to be thoroughly passing over it with hot glue once I test the button and SD card.

sterretje:
Without any additional hardware it's the only thing the Arduino can do to demonstrate. One could have used the Serial Monitor instead of the LED; would that have been better?

Good point; what I really meant was the use of the word "blink" which kind of limits the thinking in some peoples' minds.

Oh damnit, you have to be kidding me.

from first glace at least, it looks like you can't change the damn pins that the SD library uses, but those are already taken up, and it would be so much work to re wire the lcd module and figure out what was connected where, it's completely glued in and it's been a year and a half at least.

Damnit, apparently on the pro mini pin 10 has to be an output too? Sigh, there has to be some workaround for this, or it's going to be so much damn work.

Sigh, I'll wait to see if maybe someone knows of a way to do this but it looks like I basically need to tear this whole thing apart and build it again from scratch, god.

Now I need to check for sure if liquidcrystal will work on the other pins, and I think I saw something about pins a1 and a0 being the internal spi bus, so you can't use them as digital inputs/outputs or something?

The standard LCD can work on different pins. I've done it because I considered it silly to use the two available external interrupt pins (although I did not need them at that time); simply moved the all 2 positions up.

I was poking around figuring out how I'd do this and I noticed the end of the board has two analog pins! I thought that it was just more power/ground (there is a ground) and raw pins, but no, there's two more pins, and the lcd actually isn't on any of the ones I need!

That means I was able to shift the connections for the status LED and the one wire bus over, and holy crap I have pins 10-13 free! I can friggin do this!

God, I had so much dread, it was a nightmare.

Alright so getting things set up, slight issue. I have the LCD display starting and the version number as well as testing the LED's, and then afterwards I want to check for the SD card and display whether it is there or not.

Now, this is working, except for an issue with the delay. I have the LCD wait one second on the first "screen", and I would like it to do the same for the sd status one, but it does not work the way I would expect. Instead, there is a one second delay between the test screen and the SD fail message, but with the sd card in, I get it almost instantly, and it disappears equally as quickly.

This did have a return statement originally, but I haven't worked with those and it doesn't seem to fit, an if/else statement would be easier to use too, but for some reason it's not quite working right.

void setup(void) {
  pinMode(A0, OUTPUT);
  pinMode(A3, OUTPUT);
  Serial.begin(115200);                       //Start serial + LCD/Light test
  lcd.begin(8, 2);
  lcd.setCursor(0,0);
  lcd.print("STARTING");
  lcd.setCursor(0, 1);
  lcd.print("VER. 1.2");
  digitalWrite(A0, HIGH);
  digitalWrite(A3, LOW);
  delay(1000);
  digitalWrite(A0, LOW);
  digitalWrite(A3, HIGH);
  lcd.clear();                                //End of LCD/Light test

  if (!SD.begin(10)) {                       // Check for SD card
    lcd.setCursor(0,0);
    lcd.print("SD CHECK");
    lcd.setCursor(0,1);
    lcd.print("  FAIL  ");
    delay(1000);
    lcd.clear();
  } else {
    lcd.setCursor(0,0);
    lcd.print("SD CHECK");
    lcd.setCursor(0,1);
    lcd.print("  PASS  ");
    delay(1000);
    lcd.clear();
  }
}

the original test of the sd card, which just piped it out to serial, and I think waits until there is an SD card, but I don't want to do this.

 if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

Oh man I totally blanked, and turns out I already have used currentmillis in this thing lol. I wonder if you can have two running with different names, probably. I could also log once every second or whatever the measurement time is set to, I'm just working on getting the sd set up atm though.

edit: Hmm, I set it to check for the temperature stability every 20 seconds, but it sure does it more often than that, I mean I like how it works, it's just weird, unless I am not getting how I implemented it ages ago lol.

XOIIO:
the original test of the sd card, which just piped it out to serial, and I think waits until there is an SD card, but I don't want to do this.

You must not 'think' but test. I don't have an SD card reader so I'm allowed to 'think' ( :smiley: ) that there is a timeout in the SD.begin() method. Check the library if you want to be sure.

XOIIO:
edit: Hmm, I set it to check for the temperature stability every 20 seconds, but it sure does it more often than that, I mean I like how it works, it's just weird, unless I am not getting how I implemented it ages ago lol.

You check every 20 seconds if the LED needs to be set; you however check every iteration of loop() if it needs to be cleared.

And yes, you can have multiple 'timers'; just use different names for previousMillis (as far as I can see).

Alright so I tried moving the setup for the unsigned long int up above the setup as that's where it is in the example but for some reason, that stops it from working, and either way changing the interval does nothing.

I am a bit tired but damn this is annoying, I can't even figure out my own friggin code. (which didn't even work properly in the first place). Checking 1 second or so seems like it would be a good option once I do figure this damn thing out, then writing to the sd card every 5 seconds should be easy, and all that remains is the damn button. (and creating a new log file every time you start/stop datalogging, named log 0001, or log 0002, etc.

this is the full code so far, since I've been toying with it although it hasn't really gotten me anywhere.

#include <OneWire.h>
#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>
const int chipSelect = 10;

OneWire  ds(9);
LiquidCrystal lcd(6, 7, 5, 4, 3, 2);
float lasttemp;                              //Variable for last temperature
float delta;                                 //Variable for temperaturechange
long previousMillis = 0;
const long interval = 1000;                       //Check once every 20 seconds

const long sdinterval = 1000;
long sdpreviousMillis = 0;


File myFile;

void setup(void) {
  pinMode(A0, OUTPUT);
  pinMode(A3, OUTPUT);
  Serial.begin(115200);                       //Start serial + LCD/Light test
  lcd.begin(8, 2);
  lcd.setCursor(0,0);
  lcd.print("STARTING");
  lcd.setCursor(0, 1);
  lcd.print("VER. 1.2");
  digitalWrite(A0, HIGH);
  digitalWrite(A3, LOW);
  delay(1000);
  digitalWrite(A0, LOW);
  digitalWrite(A3, HIGH);
  lcd.clear();                                //End of LCD/Light test

  if (!SD.begin(10)) {                       // Check for SD card
    digitalWrite(A3, LOW);
    lcd.setCursor(0,0);
    lcd.print("SD CHECK");
    lcd.setCursor(0,1);
    lcd.print("  FAIL  ");
    delay(1000);
    lcd.clear();
    digitalWrite(A3, HIGH);
  } else {
    digitalWrite(A3, LOW);
    lcd.setCursor(0,0);
    lcd.print("SD CHECK");
    lcd.setCursor(0,1);
    lcd.print("  PASS  ");
    delay(1000);
    lcd.clear();
    digitalWrite(A3, HIGH);
  }
  
}

  
void loop(void) {

  unsigned long sdcurrentMillis = millis();
  unsigned long currentMillis = millis();

  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;

  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
  }
  Serial.println();

  // the first ROM byte indicates which chip
  switch (addr[0]) {
  case 0x10:
    Serial.println("  Chip = DS18S20");  // or old DS1820
    type_s = 1;
    break;
  case 0x28:
    Serial.println("  Chip = DS18B20");
    type_s = 0;
    break;
  case 0x22:
    Serial.println("  Chip = DS1822");
    type_s = 0;
    break;
  default:
    Serial.println("Device is not a DS18x20 family device.");
    return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } 
  else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }

  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");

  delta = celsius - lasttemp;                       //Create value to check how much temperature has changed

  if (currentMillis - previousMillis >= interval) {  //If it has been 20 seconds, check to turn LED on
    previousMillis = currentMillis;
    if ((delta < 00.03) && (delta > -00.03)) {      //If temperature hasn't changed by +/- .05 turn led on.
      digitalWrite(A0, HIGH); 
    }
  }
  if (delta >= 00.06) {                             //If temperature has changed by more than .1 turn LED off
    digitalWrite(A0, LOW);
  }
  if (delta <= -00.06) {
    digitalWrite(A0, LOW);                         // If temperature has changed by more than -.1 turn LED off
  }

  if (sdcurrentMillis - sdpreviousMillis >= sdinterval) {
    sdpreviousMillis = sdcurrentMillis;
    digitalWrite(A3, LOW);
    delay(50);
    digitalWrite(A3, HIGH);
  }


  lcd.setCursor(0, 0);
  lcd.print(celsius);
  lcd.print(" C ");
  lcd.setCursor(0, 1);
  lcd.print(fahrenheit);
  lcd.print(" F ");
  lasttemp = celsius;
}

EDIT Updated the code, I was missing the damn equal sign, so I've got the LED flashing somewhat steadily, however there are times when it definitely takes more than one second in between the flashes, like there is a random delay, but from what I can tell, there should only be the two which I put in (250ms and 1000ms), but it's definitely random, or at least as far as I can tell without a scope to time it.

So it should actually flash once every 2.250 seconds on the dot, but it's not quite doing it.

Working on getting the button to work now, you will have to hold it for a second or so due to the delays in the script, but hopefully it shouldn't be an issue. It's being finicky of course.

I would like to get rid of those delays but not sure how I could, I mean maybe with more millisecond counters or something but it seems that would just complicate things even more.

Edit: man this thing just refuses to co-operate with me, god. If I could have two loops simultaneously it would be so much simpler.

Have it writing to the sd card every 5 seconds for now, and it seems that the other delays in the script don't affect it. I had it set to 3750ms to compensate, but it was around 3.8 seconds each time it wrote, so set it to 5000ms again and it seems good. Maybe the button thing will work instantly after all, I'm not sure.

That's basically the last thing I need to do aside from the file name management, or maybe just putting in a line that says "New log starting" every time you start a log.

#include <OneWire.h>
#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>
const int chipSelect = 10;

OneWire  ds(9);                               //Onewire + lcd setup
LiquidCrystal lcd(6, 7, 5, 4, 3, 2);
float lasttemp;                              //Variable for last temperature
float delta;                                 //Variable for temperaturechange
long previousMillis = 0;
const long interval = 1000;                       //Check once every 20 seconds

const long sdinterval = 5000;
long sdpreviousMillis = 0;


File myFile;

void setup(void) {
  pinMode(A0, OUTPUT);
  pinMode(A3, OUTPUT);
  
  Serial.begin(115200);                       //Start serial + LCD/Light test
  lcd.begin(8, 2);
  lcd.setCursor(0,0);
  lcd.print("STARTING");
  lcd.setCursor(0, 1);
  lcd.print("VER. 1.2");
  digitalWrite(A0, HIGH);
  digitalWrite(A3, LOW);
  delay(1000);
  digitalWrite(A0, LOW);
  digitalWrite(A3, HIGH);
  lcd.clear();                                //End of LCD/Light test

  if (!SD.begin(10)) {                       // Check for SD card
    digitalWrite(A3, LOW);
    lcd.setCursor(0,0);
    lcd.print("SD CHECK");
    lcd.setCursor(0,1);
    lcd.print("  FAIL  ");
    delay(1000);
    lcd.clear();
    digitalWrite(A3, HIGH);
  } else {
    delay(1000);
    digitalWrite(A3, LOW);
    lcd.setCursor(0,0);
    lcd.print("SD CHECK");
    lcd.setCursor(0,1);
    lcd.print("  PASS  ");
    delay(1000);
    lcd.clear();
    digitalWrite(A3, HIGH);
  }
}
  

  
void loop(void) {

  unsigned long sdcurrentMillis = millis();
  unsigned long currentMillis = millis();
{
  }

  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;

  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
  }
  Serial.println();

  // the first ROM byte indicates which chip
  switch (addr[0]) {
  case 0x10:
    Serial.println("  Chip = DS18S20");  // or old DS1820
    type_s = 1;
    break;
  case 0x28:
    Serial.println("  Chip = DS18B20");
    type_s = 0;
    break;
  case 0x22:
    Serial.println("  Chip = DS1822");
    type_s = 0;
    break;
  default:
    Serial.println("Device is not a DS18x20 family device.");
    return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } 
  else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }

  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");

  delta = celsius - lasttemp;                       //Create value to check how much temperature has changed

  if (currentMillis - previousMillis >= interval) {  //If it has been 20 seconds, check to turn LED on
    previousMillis = currentMillis;
    if ((delta < 00.03) && (delta > -00.03)) {      //If temperature hasn't changed by +/- .05 turn led on.
      digitalWrite(A0, HIGH); 
    }
  }
  if (delta >= 00.06) {                             //If temperature has changed by more than .1 turn LED off
    digitalWrite(A0, LOW);
  }
  if (delta <= -00.06) {
    digitalWrite(A0, LOW);                         // If temperature has changed by more than -.1 turn LED off
  }


    if (sdcurrentMillis - sdpreviousMillis >= sdinterval) {  //Write to SD card every 5 seconds.
    sdpreviousMillis = sdcurrentMillis;
    digitalWrite(A3, LOW);
    myFile = SD.open("Log.txt", FILE_WRITE);
    myFile.println(celsius);
    myFile.print(" C ");
    myFile.close();
    digitalWrite(A3, HIGH);
  }

  lcd.setCursor(0, 0);
  lcd.print(celsius);
  lcd.print(" C ");
  lcd.setCursor(0, 1);
  lcd.print(fahrenheit);
  lcd.print(" F ");
  lasttemp = celsius;
  }