How would I make this if statement? (if somehting is within x amount?)

I was just wondering how I would make an if statement like this, for measuring temperature, I want an indicator when it has stabilized, so if the temperature is withing + or - .20, then the if statement would continue. How would I do this? I know that I'll need to set a variable that changes so basically it would be if current temp is within plus or minus .20 of the last temp then it would do whatever I needed.

Think about the arithmetic you have to perform to make this decision yourself.

AWOL:
Think about the arithmetic you have to perform to make this decision yourself.

well I know how to do it with more than one line, I was just hoping there was a way to do it all in one if statement, instead of two like this.

if (celsius == lasttemp + .20){
if (celsius == lasttemp - .20){
digitalWrite(13, HIGH);
else {
digitalWrite(13, LOW);
}
}
}

whoops, that should actually be this.

if (celsius == lasttemp + .20) {
if (celsius == lasttemp - .20) {
digitalWrite(13, HIGH);
}
else {
digitalWrite(13, LOW);
}
}

I'll check out boolean

  if (celsius == lasttemp + .20){
    if (celsius == lasttemp - .20){

How can celcius be equal to two different values at the same time?

I think you're looking for something like this:

if ( (celcius >= lasttemp - 0.20) && (celcius <= lasttemp + 0.20) )

You could use abs

Arrch:

  if (celsius == lasttemp + .20){

if (celsius == lasttemp - .20){




How can celcius be equal to two different values at the same time?

I think you're looking for something like this:



if ( (celcius >= lasttemp - 0.20) && (celcius <= lasttemp + 0.20) )

Ahh, that does make more sense, I guess that's what you get for staying upt oo long, thank you.

Also, I didn't know about that && thing, that's gonna be usefull.

Also, I didn't know about that && thing, that's gonna be usefull.

So is abs.

hmm, now I've got to work on scripting this right. If I have this section at the start of the script then it doesn't turn the LED on. If I have it at the end the LED stays on permanently. hmmm

if ( (celsius >= lasttemp - 0.2) && (celsius <= lasttemp + 0.2) ) {
digitalWrite(13, HIGH);
}
else {
digitalWrite(13, LOW);
}

XOIIO:
hmm, now I've got to work on scripting this right. If I have this section at the start of the script then it doesn't turn the LED on. If I have it at the end the LED stays on permanently. hmmm

Start of what? End of What? All you've posted is snippets.

Arrch:

XOIIO:
hmm, now I've got to work on scripting this right. If I have this section at the start of the script then it doesn't turn the LED on. If I have it at the end the LED stays on permanently. hmmm

Start of what? End of What? All you've posted is snippets.

ahh true. Here's the whole thing.

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

OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)
LiquidCrystal lcd(6, 7, 5, 4, 3, 2);
float lasttemp;

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

void loop(void) {
  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");
  lasttemp = celsius;
  lcd.setCursor(0, 0);
  lcd.print(celsius);
  lcd.print(" C ");
  lcd.setCursor(0, 1);
  lcd.print(fahrenheit);
  lcd.print(" F ");
  Serial.print(lasttemp);
  Serial.println();
  
    if ( (celsius >= lasttemp - 0.2) && (celsius <= lasttemp + 0.2) ) {
      digitalWrite(13, HIGH); }
      else {
        digitalWrite(13, LOW);
      }
}

I've tried using a variable to set the led state, but that got the same result.

I kind of know why it's doing it but I can't figure out a solution.

oh wait, maybe if I throw that whole thing into a while statement it will work.

hmm, well that didn't work, I'll try another way but not sure if that will work either.

  celsius = (float)raw / 16.0;
  ...
  lasttemp = celsius;
  ...
    if ( (celsius >= lasttemp - 0.2) && (celsius <= lasttemp + 0.2) ) {
      digitalWrite(13, HIGH); }
      else {
        digitalWrite(13, LOW);
      }
}

At the time that it gets to the if statement, lasttemp will be equal to celcius. That means that celcius - lasttemp will be equal to 0 every time. 0 is between -0.2 and 0.2, so how can you expect anything other than the if statement always being true?

Arrch:

  celsius = (float)raw / 16.0;

...
 lasttemp = celsius;
 ...
   if ( (celsius >= lasttemp - 0.2) && (celsius <= lasttemp + 0.2) ) {
     digitalWrite(13, HIGH); }
     else {
       digitalWrite(13, LOW);
     }
}




Yeah, the problem is that that is when the Celsius actually has a value. I've tried putting this section at the top of the loop, but it doesn't do anything since it has been reset.

Also, that while loop theory didn't pan out.

At the time that it gets to the if statement, lasttemp will be equal to celcius. That means that celcius - lasttemp will be equal to 0 every time. 0 is between -0.2 and 0.2, so how can you expect anything other than the if statement always being true?

for example when I throw it in after celsius has been declared in the loop, the led turns on once, then doesn't again.

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

OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)
LiquidCrystal lcd(6, 7, 5, 4, 3, 2);
float lasttemp;
int ledstate;

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

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
      if ( (celsius >= lasttemp - 0.2) && (celsius <= lasttemp + 0.2) ) {
      digitalWrite(13, HIGH); }
      else {
        digitalWrite(13, LOW);
      }

  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");
  lasttemp = celsius;
  lcd.setCursor(0, 0);
  lcd.print(celsius);
  lcd.print(" C ");
  lcd.setCursor(0, 1);
  lcd.print(fahrenheit);
  lcd.print(" F ");
  Serial.print(lasttemp);
  Serial.println();
  
}

Work flow:

  1. calculate the value of celcius
  2. check if the derivative is within a certain range
  3. update the lasttemp variable
float celsius, fahrenheit;
  
      if ( (celsius >= lasttemp - 0.2) && (celsius <= lasttemp + 0.2) ) {

Pluck some random value off the stack and compare it to lasttemp?
Not good - It might not even be a valid "float".

AWOL:

float celsius, fahrenheit;

if ( (celsius >= lasttemp - 0.2) && (celsius <= lasttemp + 0.2) ) {



Pluck some random value off the stack and compare it to lasttemp?
Not good - It might not even be a valid "float".

well the float is appearing in serial just fine, I'm thinking this just happens too fast to give the LED a chance to turn off. A way to fix that would be to delay but I need it to update constantly. I'm really not sure how this could be done, or if it even can be. Maybe it would need to be the last 3 temps or something, I wonder how you would rig that up.

I think I might just need to forget this part and leave it as is.

XOIIO:
well the float is appearing in serial just fine,

That because by the time you've printed it, you've given it a value.