1

I want to put a 2 seconds delay to temperature reading but the millis() delay is not applying.

#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2

Time t;
LiquidCrystal_I2C lcd(0x27, 16, 2);
DS3231  rtc(SDA, SCL);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

const int OnHour = 23;
const int OnMin = 42;
const int checkTemp = 2000;
const int checkTempinterval = 0;

void setup() {
  Serial.begin(115200);
  pinMode(3, OUTPUT);
  lcd.begin();
  lcd.backlight();
  rtc.begin();
}
void loop() {
  t = rtc.getTime();
  float testTemp;
  testTemp = temperature();
  lcd.setCursor(0,0);
  lcd.print(testTemp);
  lcd.print("   ");
  lcd.print(rtc.getTimeStr());
  lcd.setCursor(0,1);
  lcd.print(rtc.getDOWStr());
  lcd.print("   ");
  lcd.print(rtc.getDateStr());
  if(testTemp >= 28){
    digitalWrite(3,HIGH);
  }else{
    digitalWrite(3,LOW);
  }
//  if(t.hour == OnHour && t.min == OnMin){
//    digitalWrite(3,HIGH);
//  }else{
//    digitalWrite(3,LOW);
//  }
}
float temperature(){
  unsigned long currenttime = millis();
  if(currenttime - checkTempinterval >= checkTemp){
  sensors.requestTemperatures();
  float testTemp = sensors.getTempCByIndex(0);
  currenttime = checkTempinterval;
  return testTemp;
  }
}
10
  • First of all, not all execution paths are returning the value, second of all, why are you doing: currenttime = checkTempinterval;, it's pointless as it won't exist anymore after the return.
    – KIIV
    Commented Jun 15, 2019 at 20:35
  • There is nothing called "minis" in your code example.
    – st2000
    Commented Jun 15, 2019 at 20:35
  • @KIIV so i can't return value from sensors.getTempCByIndex(0);? it's reading the temp but the delay is not applying... Commented Jun 15, 2019 at 20:37
  • You can, but code is not doing it in case the if condition fails.
    – KIIV
    Commented Jun 15, 2019 at 20:44
  • @KIIV so what's the solution? Commented Jun 15, 2019 at 20:44

2 Answers 2

3

I see 2 problems with your code:

  1. Returning a value from a function: If you want to return a value from a function, you will have to make sure, that in any case the return x statement is executed inside the function in the temperature() function you currently have this if statement:

    if(currenttime - checkTempinterval >= checkTemp){
    

    Inside of it is the only return statement. That means, if the function is called before the next measurement time, the function will not return anything. Normally the compiler gives you at least a warning about that (maybe you have to turn the warnings on in the settings of the Arduino IDE).

    Here you also have to think about, what you want to return, if no measurement was actually executed. Do you want to return an error value (for example -300; the error value should not be found inside valid data)? Then do so after the if statement. Or do you want it to simply return the last measured value? Then declare a variable (either at global scope, meaning outside of any function, or at local scope, meaning inside the function, but static, which means that the value will be retained between the functions executions). Save the measured temperatures to this variable and return it after the if statement.

    If you do this, also consider what that means for the rest of your code. For example, if you return an error value, currently it will also be displayed by your code.

  2. Doing the millis() code correctly: What you are doing wrong here, it that you update the wrong variable inside the if statement. Currently you write the value of checkTempinterval (which is the time of the last measurement) to the variable currenttime. The variable currenttime was declared locally (meaning inside the function) by using

    unsigned long currenttime = millis();
    

    Local variables are only present during the execution of the function, that they are declared in. When the microcontroller has executed the return statement, it will throw all local variables away, making the RAM free for other variables. That means currently you are saving a value inside a variable, that get's thrown away directly after it.

    What you actually meant to do, was to do it vice versa:

    checkTempinterval = currenttime;
    

    checkTempinterval is a global variable. It will stay in RAM during the whole program execution. Since it holds the last measurement time, you write the currenttime to it, when you measure.

    Very important: Currently checkTempinterval is defined as const int meaning constant integer. This variable must not be constant, since we want to change the value (update the time of the last measurement). Also you should not use int here, because it's value range goes only up to 32767, which is 32 seconds when used with millis(). After that, it will overflow to negative values. Better use the type of millis() return value: unsigned long. It has 4 byte (instead of ints 2 byte) and will only overflow after 49 days. If you only use this variable type for things with millis(), even this overflow will not be a problem.

0
1

You can use the millis() function to create a "timer" that will get the sensor reading every 2 seconds. The sketch BlinkWithoutDelay.ino, should come with the Arduino IDE, but if not, you can find it here: BlinkWithoutDelay.

I've used that exact sketch with some modifications to display the results on the Serial Monitor instead of blinking an LED. When you are creating something, using the Serial Monitor can help you to De-bug your sketch.

Please read the code comments in the following sketch. Once you have this working with your code, then you could decide if you need a function or not.

// Store the last time you checked the sensor.
unsigned long previousMillis = 0;

// interval at which to checked the sensor (milliseconds)
const long interval = 2000;

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

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // Get the current time.
  unsigned long currentMillis = millis();

  // Check to see if it's time to check the sensor reading.
  if (currentMillis - previousMillis >= interval) {
    // save the last time you checked the sensor.
    previousMillis = currentMillis;

    // This is where you add the code that checks the sensor.

    // Test output.
    Serial.println("Checking Sensor");
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.