Pages: 1 [2] 3 4   Go Down
Author Topic: How would I make this if statement? (if somehting is within x amount?)  (Read 2019 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
#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();
 
}
Logged

California
Offline Offline
Faraday Member
**
Karma: 88
Posts: 3364
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Work flow:

1) calculate the value of celcius
2) check if the derivative is within a certain range
3) update the lasttemp variable
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25795
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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".
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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.
Logged

California
Offline Offline
Faraday Member
**
Karma: 88
Posts: 3364
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

well the float is appearing in serial just fine,

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

Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hmm, I got something, I added a counter so it only would check if celsius equals the lasttemp every second time, and the led flashes when the temp is changing, then stays solid. That's not bad actually, although it still stays onw ith soe change, I'll try doubling or tripling the counter and seeing how that goes.


Code:
#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;
int counter = 0;

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");

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

  lasttemp = celsius;
  lcd.setCursor(0, 0);
  lcd.print(celsius);
 
  if ( (counter % 2) == 0) {
    if ( (celsius >= lasttemp - 0.10) && (celsius <= lasttemp + 0.10) ) {
    digitalWrite(13, HIGH);
  }
  else {
    digitalWrite(13, LOW);
  }
  }
 
  lasttemp == celsius;
  ++counter;
  lcd.print(" C ");
  lcd.setCursor(0, 1);
  lcd.print(fahrenheit);
  lcd.print(" F ");
  Serial.print(lasttemp);
  Serial.println();
}
Logged

California
Offline Offline
Faraday Member
**
Karma: 88
Posts: 3364
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  lasttemp = celsius;
  ...
  if ( (counter % 2) == 0) {
    if ( (celsius >= lasttemp - 0.10) && (celsius <= lasttemp + 0.10) ) {

Same issue as before, the second if statement will always evaluate to true, so you may as well remove it.
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  lasttemp = celsius;
  ...
  if ( (counter % 2) == 0) {
    if ( (celsius >= lasttemp - 0.10) && (celsius <= lasttemp + 0.10) ) {

Same issue as before, the second if statement will always evaluate to true, so you may as well remove it.

whoops, thought I had deleted that one
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hmm, so I relaxed the limits a bit, and the temperature is stable (the lcd displays way faster than serial), however the led doesn't turn on at all. I know for a fact that the counter is working too. hmm

Code:
  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");

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

  lcd.setCursor(0, 0);
  lcd.print(celsius);
 
  if ( (counter % 2) == 0) {
    if ( (celsius >= lasttemp - 0.50) && (celsius <= lasttemp + 0.50) ) {
    digitalWrite(13, HIGH);
  }
  else {
    digitalWrite(13, LOW);
  }
  }
 
  lcd.print(" C ");
  lcd.setCursor(0, 1);
  lcd.print(fahrenheit);
  lcd.print(" F ");
  lasttemp == celsius;
  ++counter;
}
Logged

California
Offline Offline
Faraday Member
**
Karma: 88
Posts: 3364
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  lasttemp == celsius;

== is for comparison like in if statements
= is for assignments.
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  lasttemp == celsius;

== is for comparison like in if statements
= is for assignments.

ah shit that's right. *facepalm*

Now I just need to get that counter to work better, so that it checks once every, hmm, 6 times or something. I don't know exactly, but I want to compare the temperatures between the last 30 seconds, that would make sure it has normalized
« Last Edit: June 21, 2013, 10:32:04 am by XOIIO » Logged

California
Offline Offline
Faraday Member
**
Karma: 88
Posts: 3364
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

but I want to compare the temperatures between the last 30 seconds, that would make sure it has normalized

The Blink Without Delay example demonstrates on how to perform periodic actions (such as comparing values 30 seconds apart) without blocking the rest of your code.
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

but I want to compare the temperatures between the last 30 seconds, that would make sure it has normalized

The Blink Without Delay example demonstrates on how to perform periodic actions (such as comparing values 30 seconds apart) without blocking the rest of your code.

yup, that occurred to me just a little while ago, and it's working-ish, there is some fluctuation with the LED but I do have a fan going. Aside from that it seems to be working peachy.

Code:
#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;
int counter = 0;
long previousMillis = 0;
long interval = 10000;

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) {
  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");

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

  lcd.setCursor(0, 0);
  lcd.print(celsius);

  if (currentMillis - previousMillis > interval) {
    if ( (celsius >= lasttemp - 0.05) && (celsius <= lasttemp + 0.05) ) {
    digitalWrite(13, HIGH);
  }
  else {
    digitalWrite(13, LOW);
  }
  }
 
  lcd.print(" C ");
  lcd.setCursor(0, 1);
  lcd.print(fahrenheit);
  lcd.print(" F ");
  lasttemp = celsius;
}
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hmm, im having a bit of trouble figuring this out actually. I need it to check once every 30 seconds (got that part down) if the temperature has stayed the same the last 30 seconds. thing is, if I put the same delay on the temperature, of course it will match. hmmm
Logged

California
Offline Offline
Faraday Member
**
Karma: 88
Posts: 3364
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Would do you mean by "put the same delay on the temperature"?
Logged

Pages: 1 [2] 3 4   Go Up
Jump to: