Resetting millis

My little code got massive with a lot of help from this forum.
Thanks everyone that helps out.

My code turns on and off relays that control dew point and temp. It now runs one setting for four days then changes the dew point for four days.

How can i make it go back to the original dew point after another 4 days. So four days at 12 then four days at 11, then back to 12 indefinitely?

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>


double dewPoint(double celsius, double humidity) {
  // (1) Saturation Vapor Pressure = ESGG(T)
  double RATIO = 373.15 / (273.15 + celsius);
  double RHS = -7.90298 * (RATIO - 1);
  RHS += 5.02808 * log10(RATIO);
  RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / RATIO))) - 1);
  RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1);
  RHS += log10(1013.246);

  // factor -3 is to adjust units - Vapor Pressure SVP * humidity
  double VP = pow(10, RHS - 3) * humidity;

  // (2) DEWPOINT = F(Vapor Pressure)
  double T = log(VP / 0.61078);  // temp var
  return (241.88 * T) / (17.558 - T);
}


#include "DHT.h"

#define DHTPIN 11  // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11  // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)


// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);

//DHT dht(DHTPIN, DHTTYPE, 30);

int intakefan = 2;  //  Intake fan for Humid box and dry box
int humidv = 3;     //  Valve for humud intake
int dryv = 4;       // dry box valve
int exfan = 5;      // exhaust fan
int exv = 6;        // exhaust valve
int returnfan = 7;  // fan to bring air from inside box
int returnv = 8;    //  return valve, air from inside box
//int lock = 9;       // Electric lock
int fridge = 13;  // relay to fridge 240v

int DHTpower = 12;  // constant 5v to DHT11

unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 30000000;  //the value is a number of milliseconds


LiquidCrystal_I2C lcd(0x27, 16, 2);  // Set the LCD address to 0x27 for a 16x2 display

void setup() {
  pinMode(intakefan, OUTPUT);
  pinMode(fridge, OUTPUT);
  pinMode(humidv, OUTPUT);
  pinMode(dryv, OUTPUT);
  pinMode(exfan, OUTPUT);
  pinMode(exv, OUTPUT);
  pinMode(returnfan, OUTPUT);
  pinMode(returnv, OUTPUT);
  pinMode(DHTpower, OUTPUT);

  digitalWrite(intakefan, LOW);
  digitalWrite(humidv, LOW);
  digitalWrite(dryv, LOW);
  digitalWrite(exfan, LOW);
  digitalWrite(exv, LOW);
  digitalWrite(returnfan, LOW);
  digitalWrite(returnv, LOW);
  digitalWrite(DHTpower, HIGH);
  digitalWrite(fridge, LOW);


  Serial.begin(9600);
  lcd.init();       // Initialize the LCD
  lcd.backlight();  // Turn on the backlight
  lcd.clear();      // Clear the LCD screen
  lcd.setCursor(3, 0);
  lcd.print("The Green");
  lcd.setCursor(4, 1);
  lcd.print("Ninja");
  delay(2000);  // Display the startup message for 2 seconds
  lcd.clear();
  dht.begin();
  startMillis = millis();  //initial start time
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
  float currentDew = dewPoint(t, h);  // Dew Point for setting pins high

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    lcd.clear();
    lcd.print("Failed to read from DHT sensor!");

    return;
  }

  // Compute heat index
  // Must send in temp in Fahrenheit!
  float hi = dht.computeHeatIndex(f, h);
  float hiDegC = dht.convertFtoC(hi);



  if (f < 19) {
    digitalWrite(fridge, LOW);
  }

  if (f > 21) {
    digitalWrite(fridge, HIGH);
  }



  //  first 4 days
  currentMillis = millis();                   //get the current "time" (actually the number of milliseconds since the program started)
  if (currentMillis - startMillis <= period)  //test less than period
    if (currentDew > 11.5 && (currentDew < 12.5))
      ;  // Level to aim for dew point 12
  {
    digitalWrite(intakefan, LOW);
    digitalWrite(humidv, LOW);
    digitalWrite(dryv, LOW);
    digitalWrite(exfan, LOW);
    digitalWrite(exv, LOW);
    digitalWrite(returnfan, LOW);
    digitalWrite(returnv, LOW);
    lcd.print("Dew point OK");
    lcd.setCursor(0, 1);
    lcd.print(dewPoint(t, h));
    lcd.setCursor(5, 0);
    lcd.print("c");
    delay(2000);
    lcd.clear();
    lcd.print("Temperature");
    lcd.setCursor(0, 1);
    lcd.print(dht.readTemperature());
    lcd.setCursor(5, 0);
    lcd.print("c");
    delay(2000);
    lcd.clear();
    lcd.print("Humidity");
    lcd.setCursor(0, 1);
    lcd.print(dht.readHumidity());
    lcd.setCursor(5, 0);
    lcd.print("%");
    delay(2000);
    lcd.clear();
    lcd.print("Dry Cycle");
    delay(2000);
  }
  if (currentDew > 12.5)
    ;
  {  //   High dew point, send to dry box
    digitalWrite(humidv, LOW);
    digitalWrite(dryv, HIGH);
    digitalWrite(exv, HIGH);
    digitalWrite(returnv, HIGH);
    lcd.clear();
    lcd.print("Dew Point High");
    lcd.setCursor(0, 1);
    lcd.print(dewPoint(t, h));
    lcd.setCursor(5, 0);
    lcd.print("c");
    delay(2000);
    lcd.clear();
    lcd.print("Temperature");
    lcd.setCursor(0, 1);
    lcd.print(dht.readTemperature());
    lcd.setCursor(5, 0);
    lcd.print("c");
    delay(2000);
    lcd.clear();
    lcd.print("Dry Box On");
    lcd.setCursor(0, 1);
    lcd.print("Fans On");
    digitalWrite(intakefan, HIGH);
    digitalWrite(exfan, HIGH);
    digitalWrite(returnfan, HIGH);
    delay(2000);
    lcd.clear();
    lcd.print("Humidity");
    lcd.setCursor(0, 1);
    lcd.print(dht.readHumidity());
    lcd.setCursor(5, 0);
    lcd.print("%");
    delay(2000);
  }
  if (currentDew < 11.5)
    ;
  {  // Dew point low, send to humid box
    digitalWrite(humidv, HIGH);
    digitalWrite(dryv, LOW);
    digitalWrite(exv, HIGH);
    digitalWrite(returnfan, LOW);
    digitalWrite(returnv, LOW);
    lcd.print("Dew point LOW");
    lcd.setCursor(0,1);
    lcd.print(dewPoint(t, h));
    lcd.setCursor(5,0);
    lcd.print("c");
    delay(2000);
    digitalWrite(intakefan, HIGH);
    digitalWrite(exfan, HIGH);
    lcd.clear();
    lcd.print("Humid Box On");
    lcd.setCursor(0, 1);
    lcd.print("Fans On");
    delay(2000);
    lcd.clear();
    lcd.print("Dew Point Low");
    lcd.setCursor(0, 1);
    lcd.print(dewPoint(t, h));
    delay(2000);
    lcd.clear();
    lcd.print("Temperature");
    lcd.setCursor(0, 1);
    lcd.print(dht.readTemperature());
    delay(2000);
    lcd.clear();
    lcd.print("Humidity");
    lcd.setCursor(0, 1);
    lcd.print(dht.readHumidity());
    lcd.clear();
    //
    //  after 4 days  //  //

    if (currentMillis - startMillis >= period)  //test whether the period has elapsed
      if (currentDew > 10.5 && (currentDew < 11.5))
        ;  // Level to aim for dew point 11
    {

      digitalWrite(intakefan, LOW);
      digitalWrite(humidv, LOW);
      digitalWrite(dryv, LOW);
      digitalWrite(exfan, LOW);
      digitalWrite(exv, LOW);
      digitalWrite(returnfan, LOW);
      digitalWrite(returnv, LOW);
      lcd.print("Dew point OK");
      lcd.print(dewPoint(t, h));
      lcd.clear();
      lcd.print("Temperature");
      lcd.setCursor(0, 1);
      lcd.print(dht.readTemperature());
      delay(2000);
      lcd.clear();
      lcd.print("Humidity");
      lcd.setCursor(0, 1);
      lcd.print(dht.readHumidity());
    }
    if (currentDew > 11.5)
      ;
    {  //   High dew point, send to dry box
      digitalWrite(humidv, LOW);
      digitalWrite(dryv, HIGH);
      digitalWrite(exv, HIGH);
      digitalWrite(returnv, HIGH);
      lcd.clear();
      lcd.print("after 4 days");
      lcd.setCursor(0, 1);
      lcd.print(dewPoint(t, h));
      delay(2000);
      lcd.clear();
      lcd.print("Temperature");
      lcd.setCursor(0, 1);
      lcd.print(dht.readTemperature());
      delay(2000);
      lcd.clear();
      lcd.print("Dry Box On");
      lcd.setCursor(0, 1);
      lcd.print("Fans On");
      digitalWrite(intakefan, HIGH);
      digitalWrite(exfan, HIGH);
      digitalWrite(returnfan, HIGH);
      delay(2000);
      lcd.clear();
      lcd.print("Humidity");
      lcd.setCursor(0, 1);
      lcd.print(dht.readHumidity());
    }
    if (currentDew < 10.5)
      ;
    {  // Dew point low, send to humid box
      digitalWrite(humidv, HIGH);
      digitalWrite(dryv, LOW);
      digitalWrite(exv, HIGH);
      digitalWrite(returnfan, LOW);
      digitalWrite(returnv, LOW);
      lcd.print("Dew point LOW");
      lcd.print(dewPoint(t, h));
      delay(2000);
      digitalWrite(intakefan, HIGH);
      digitalWrite(exfan, HIGH);
      lcd.clear();
      lcd.print("Humid Box On");
      lcd.setCursor(0, 1);
      lcd.print("Fans On");
      delay(2000);
      lcd.clear();
      lcd.print("Dew Point Low");
      lcd.setCursor(0, 1);
      lcd.print(dewPoint(t, h));
      delay(2000);
      lcd.clear();
      lcd.print("Temperature");
      lcd.setCursor(0, 1);
      lcd.print(dht.readTemperature());
      delay(2000);
      lcd.clear();
      lcd.print("Humidity");
      lcd.setCursor(0, 1);
      lcd.print(dht.readHumidity());
      lcd.clear();
    }
  }
}

  • You are hereby promoted from newbie to pre-expert.

  • As a result you should look into how to use an RTC, suggest the DS3231.


got a warm fuzzy feeling...
:smiley:
thats what i was looking at

1 Like

If you looking at that, you needa read this:

DS3231 battery issue

a7

it's hard to tell what you're thinking

the if (currentMillis - startMillis <= period) has no braces which means the body of the if statement is just the next statement (line).

the next statement, without any braces is just

    if (currentDew > 11.5 && (currentDew < 12.5))
      ;  // Level to aim for dew point 12

which means neither of these if statements do anything

and then there's another

it's not clear how the code it tracking time/days

do you just want to do something once every 4 days?

Im making it up as i go along to be honest.

Im trying to keep the dew point at 12 for four days then at 11 for four days, then back to 12 indefinitely.

Most of the code is just copied from people until it works, im pretty new to this.

I only just started trying to understand millis.

1 Like

so there's a lot of redundant code, at least display code that could probably be put into a sub-function.

seems that for each dewpoint setting the outputs are set one way when the dewpoint is below some target, another setting when above the target and a third setting when around the target.

seems like you just need a sub-function where you specify the target and then select one of 3 control settings

does this sound right?

Let me be honest and say that will only work for so long, so long being such a short time as to make it a bad approach!

At the very least, read read read the code you find and attempt to repurpose so you understand what you are working with.

Ask questions, here is fine, about things that you read that do not make sense.

Find and use some source of basic material on beginning to program for the Arduino. There are thousands of sources, dozens anyway, spend 5 or ten minutes really looking into 5 or ten of them, that will be about an hour def not wasted.

Find a course you like, or a presenter you can tolerate - quality may vary but the good thing is that there is only one truth, so only one truth to learn.

a7

You do this kind of thing an awful lot in your code. To misquote Inigo Montoya, "I do not think this means what you think it means". It's effectively a null statement. It doesn't do anything. It certainly doesn't affect any immediately following code block that you were hoping would only be executed if that condition was true.

Yea there is a lot of lcd.print and delay, im not really sure what you mean by sub-function but ill have a look

you are right, it started as one fan and valve and ended up four valves and three fans, all got a bit much,

I know what you mean about having a sub-function where i specify a target and select one of 3 control settings, but I have no idea where to start with that.
I mean it sounds like a good idea

ok then

"ok then"? Wow.

Try this for a start.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>

#define DHTPIN 11  // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11  // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)


// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);

//DHT dht(DHTPIN, DHTTYPE, 30);

int intakefan = 2;  //  Intake fan for Humid box and dry box
int humidv = 3;     //  Valve for humud intake
int dryv = 4;       // dry box valve
int exfan = 5;      // exhaust fan
int exv = 6;        // exhaust valve
int returnfan = 7;  // fan to bring air from inside box
int returnv = 8;    //  return valve, air from inside box
//int lock = 9;       // Electric lock
int fridge = 13;  // relay to fridge 240v

int DHTpower = 12;  // constant 5v to DHT11

unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 30000000;  //the value is a number of milliseconds

float lowDewPoint, highDewPoint;
bool cycle;

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Set the LCD address to 0x27 for a 16x2 display


double dewPoint(double celsius, double humidity) {
   // (1) Saturation Vapor Pressure = ESGG(T)
   double RATIO = 373.15 / (273.15 + celsius);
   double RHS = -7.90298 * (RATIO - 1);
   RHS += 5.02808 * log10(RATIO);
   RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / RATIO))) - 1);
   RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1);
   RHS += log10(1013.246);

   // factor -3 is to adjust units - Vapor Pressure SVP * humidity
   double VP = pow(10, RHS - 3) * humidity;

   // (2) DEWPOINT = F(Vapor Pressure)
   double T = log(VP / 0.61078);  // temp var
   return (241.88 * T) / (17.558 - T);
}

void setup() {
   pinMode(intakefan, OUTPUT);
   pinMode(fridge, OUTPUT);
   pinMode(humidv, OUTPUT);
   pinMode(dryv, OUTPUT);
   pinMode(exfan, OUTPUT);
   pinMode(exv, OUTPUT);
   pinMode(returnfan, OUTPUT);
   pinMode(returnv, OUTPUT);
   pinMode(DHTpower, OUTPUT);

   digitalWrite(intakefan, LOW);
   digitalWrite(humidv, LOW);
   digitalWrite(dryv, LOW);
   digitalWrite(exfan, LOW);
   digitalWrite(exv, LOW);
   digitalWrite(returnfan, LOW);
   digitalWrite(returnv, LOW);
   digitalWrite(DHTpower, HIGH);
   digitalWrite(fridge, LOW);

   Serial.begin(9600);
   lcd.init();       // Initialize the LCD
   lcd.backlight();  // Turn on the backlight
   lcd.clear();      // Clear the LCD screen
   lcd.setCursor(3, 0);
   lcd.print("The Green");
   lcd.setCursor(4, 1);
   lcd.print("Ninja");
   delay(2000);  // Display the startup message for 2 seconds
   lcd.clear();
   dht.begin();
   startMillis = millis();  //initial start time
   
   lowDewPoint = 11.5;
   highDewPoint = 12.5;
   cycle = false;
}

void loop() {
   // Wait a few seconds between measurements.
   delay(2000);

   // Reading temperature or humidity takes about 250 milliseconds!
   // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
   float h = dht.readHumidity();
   // Read temperature as Celsius
   float t = dht.readTemperature();
   // Read temperature as Fahrenheit
   float f = dht.readTemperature(true);
   float currentDew = dewPoint(t, h);  // Dew Point for setting pins high

   // Check if any reads failed and exit early (to try again).
   if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println("Failed to read from DHT sensor!");
      lcd.clear();
      lcd.print("Failed to read from DHT sensor!");
      return;
   }

   // Compute heat index
   // Must send in temp in Fahrenheit!
   float hi = dht.computeHeatIndex(f, h);
   float hiDegC = dht.convertFtoC(hi);

   if (f < 19) {
      digitalWrite(fridge, LOW);
   }

   if (f > 21) {
      digitalWrite(fridge, HIGH);
   }

   //  first 4 days
   currentMillis = millis();                   //get the current "time" (actually the number of milliseconds since the program started)
   if (currentMillis - startMillis > period) { //test greater than period
      cycle = !cycle;                          // switch to alternate 4 day cycle
      startMillis = currentMillis;
      if( cycle ) {
         lowDewPoint = 10.5;
         highDewPoint = 11.5;
      } else {
         lowDewPoint = 11.5;
         highDewPoint = 12.5;
      }
   }
      
   if (currentDew > lowDewPoint && (currentDew < highDewPoint)) {  // Level to aim for dew point
      dewPointOk(t,h);
   }
   if (currentDew >= highDewPoint) {  //   High dew point, send to dry box
      dewPointHigh(t,h);
   }
   if (currentDew <= lowDewPoint) {  // Dew point low, send to humid box
      dewPointLow(t,h);
   }
}

void dewPointOk(float t, float h) {
   digitalWrite(intakefan, LOW);
   digitalWrite(humidv, LOW);
   digitalWrite(dryv, LOW);
   digitalWrite(exfan, LOW);
   digitalWrite(exv, LOW);
   digitalWrite(returnfan, LOW);
   digitalWrite(returnv, LOW);
   lcd.print("Dew point OK");
   lcd.setCursor(0, 1);
   lcd.print(dewPoint(t, h));
   lcd.setCursor(5, 0);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Temperature");
   lcd.setCursor(0, 1);
   lcd.print(dht.readTemperature());
   lcd.setCursor(5, 0);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Humidity");
   lcd.setCursor(0, 1);
   lcd.print(dht.readHumidity());
   lcd.setCursor(5, 0);
   lcd.print("%");
   delay(2000);
   lcd.clear();
   lcd.print("Dry Cycle");
   delay(2000);
}

void dewPointHigh(float t, float h) {
   digitalWrite(humidv, LOW);
   digitalWrite(dryv, HIGH);
   digitalWrite(exv, HIGH);
   digitalWrite(returnv, HIGH);
   lcd.clear();
   lcd.print("Dew Point High");
   lcd.setCursor(0, 1);
   lcd.print(dewPoint(t, h));
   lcd.setCursor(5, 0);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Temperature");
   lcd.setCursor(0, 1);
   lcd.print(dht.readTemperature());
   lcd.setCursor(5, 0);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Dry Box On");
   lcd.setCursor(0, 1);
   lcd.print("Fans On");
   digitalWrite(intakefan, HIGH);
   digitalWrite(exfan, HIGH);
   digitalWrite(returnfan, HIGH);
   delay(2000);
   lcd.clear();
   lcd.print("Humidity");
   lcd.setCursor(0, 1);
   lcd.print(dht.readHumidity());
   lcd.setCursor(5, 0);
   lcd.print("%");
   delay(2000);
}

void dewPointLow(float t, float h) {
   digitalWrite(humidv, HIGH);
   digitalWrite(dryv, LOW);
   digitalWrite(exv, HIGH);
   digitalWrite(returnfan, LOW);
   digitalWrite(returnv, LOW);
   lcd.print("Dew point LOW");
   lcd.setCursor(0,1);
   lcd.print(dewPoint(t, h));
   lcd.setCursor(5,0);
   lcd.print("c");
   delay(2000);
   digitalWrite(intakefan, HIGH);
   digitalWrite(exfan, HIGH);
   lcd.clear();
   lcd.print("Humid Box On");
   lcd.setCursor(0, 1);
   lcd.print("Fans On");
   delay(2000);
   lcd.clear();
   lcd.print("Dew Point Low");
   lcd.setCursor(0, 1);
   lcd.print(dewPoint(t, h));
   delay(2000);
   lcd.clear();
   lcd.print("Temperature");
   lcd.setCursor(0, 1);
   lcd.print(dht.readTemperature());
   delay(2000);
   lcd.clear();
   lcd.print("Humidity");
   lcd.setCursor(0, 1);
   lcd.print(dht.readHumidity());
   lcd.clear();
}

Sorry, thought you were taking the piss.
Been working on this thing every waking hour for months and thought I was doing well.

Thats brilliant thank you, im going to study that for days

My code changes after 4 days using millis, then after 4 days change back to the original code.Use code tags to format code for the forum

Is there a way i can end the millis or skip it some other way?

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>

#define DHTPIN 11  // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11  // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)


// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);

//DHT dht(DHTPIN, DHTTYPE, 30);

int intakefan = 2;  //  Intake fan for Humid box and dry box
int humidv = 3;     //  Valve for humud intake
int dryv = 4;       // dry box valve
int exfan = 5;      // exhaust fan
int exv = 6;        // exhaust valve
int returnfan = 7;  // fan to bring air from inside box
int returnv = 8;    //  return valve, air from inside box
//int lock = 9;       // Electric lock
int cyclereset = 10; // button to reset cycle
int fridge = 13;  // relay to fridge 240v

int DHTpower = 12;  // constant 5v to DHT11

unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 345600000;  //the value is a number of milliseconds

float lowDewPoint, highDewPoint;
bool cycle;

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Set the LCD address to 0x27 for a 16x2 display


double dewPoint(double celsius, double humidity) {
   // (1) Saturation Vapor Pressure = ESGG(T)
   double RATIO = 373.15 / (273.15 + celsius);
   double RHS = -7.90298 * (RATIO - 1);
   RHS += 5.02808 * log10(RATIO);
   RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / RATIO))) - 1);
   RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1);
   RHS += log10(1013.246);

   // factor -3 is to adjust units - Vapor Pressure SVP * humidity
   double VP = pow(10, RHS - 3) * humidity;

   // (2) DEWPOINT = F(Vapor Pressure)
   double T = log(VP / 0.61078);  // temp var
   return (241.88 * T) / (17.558 - T);
}

void setup() {
   pinMode(intakefan, OUTPUT);
   pinMode(fridge, OUTPUT);
   pinMode(humidv, OUTPUT);
   pinMode(dryv, OUTPUT);
   pinMode(exfan, OUTPUT);
   pinMode(exv, OUTPUT);
   pinMode(returnfan, OUTPUT);
   pinMode(returnv, OUTPUT);
   pinMode(DHTpower, OUTPUT);
   pinMode(cyclereset, INPUT);

   digitalWrite(intakefan, LOW);
   digitalWrite(humidv, LOW);
   digitalWrite(dryv, LOW);
   digitalWrite(exfan, LOW);
   digitalWrite(exv, LOW);
   digitalWrite(returnfan, LOW);
   digitalWrite(returnv, LOW);
   digitalWrite(DHTpower, HIGH);
   digitalWrite(fridge, LOW);
   digitalWrite(cyclereset, LOW);

   Serial.begin(9600);
   lcd.init();       // Initialize the LCD
   lcd.backlight();  // Turn on the backlight
   lcd.clear();      // Clear the LCD screen
   lcd.setCursor(3, 0);
   lcd.print("The Green");
   lcd.setCursor(4, 1);
   lcd.print("Ninja");
   delay(2000);  // Display the startup message for 2 seconds
   lcd.clear();
   dht.begin();
   startMillis = millis();  //initial start time
   
   lowDewPoint = 11.5;
   highDewPoint = 12.5;
   cycle = false;
}

void loop() {
   // Wait a few seconds between measurements.
   delay(2000);

   // Reading temperature or humidity takes about 250 milliseconds!
   // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
   float h = dht.readHumidity();
   // Read temperature as Celsius
   float t = dht.readTemperature();
   // Read temperature as Fahrenheit
   float f = dht.readTemperature(true);
   float currentDew = dewPoint(t, h);  // Dew Point for setting pins high

   // Check if any reads failed and exit early (to try again).
   if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println("Failed to read from DHT sensor!");
      lcd.clear();
      lcd.print("Failed to read from DHT sensor!");
      return;
   }

   // Compute heat index
   // Must send in temp in Fahrenheit!
   float hi = dht.computeHeatIndex(f, h);
   float hiDegC = dht.convertFtoC(hi);

   if (f < 19) {
      digitalWrite(fridge, LOW);
   }

   if (f > 21) {
      digitalWrite(fridge, HIGH);
   }

   //  first 4 days
   currentMillis = millis();                   //get the current "time" (actually the number of milliseconds since the program started)
   if (currentMillis - startMillis > period) { //test greater than period
      cycle = !cycle;                          // switch to alternate 4 day cycle
      startMillis = currentMillis;
      if(( cycle ) || (digitalRead(cyclereset, HIGH)); {
         lowDewPoint = 10.5;
         highDewPoint = 11.5;
      } else {
         lowDewPoint = 11.5;
         highDewPoint = 12.5;
      }
   }
      
   if (currentDew > lowDewPoint && (currentDew < highDewPoint)) {  // Level to aim for dew point
      dewPointOk(t,h);
   }
   if (currentDew >= highDewPoint) {  //   High dew point, send to dry box
      dewPointHigh(t,h);
   }
   if (currentDew <= lowDewPoint) {  // Dew point low, send to humid box
      dewPointLow(t,h);
   }
}

void dewPointOk(float t, float h) {
   digitalWrite(intakefan, LOW);
   digitalWrite(humidv, LOW);
   digitalWrite(dryv, LOW);
   digitalWrite(exfan, LOW);
   digitalWrite(exv, LOW);
   digitalWrite(returnfan, LOW);
   digitalWrite(returnv, LOW);
   lcd.print("Dew point OK");
   lcd.setCursor(0, 1);
   lcd.print(dewPoint(t, h));
   lcd.setCursor(6, 1);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Temperature");
   lcd.setCursor(0, 1);
   lcd.print(dht.readTemperature());
   lcd.setCursor(6, 1);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Humidity");
   lcd.setCursor(0, 1);
   lcd.print(dht.readHumidity());
   lcd.setCursor(6, 1);
   lcd.print("%");
   delay(2000);
}

void dewPointHigh(float t, float h) {
   digitalWrite(humidv, LOW);
   digitalWrite(dryv, HIGH);
   digitalWrite(exv, HIGH);
   digitalWrite(returnv, HIGH);
   lcd.clear();
   lcd.print("Dew Point High");
   lcd.setCursor(0, 1);
   lcd.print(dewPoint(t, h));
   lcd.setCursor(6, 1);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Temperature");
   lcd.setCursor(0, 1);
   lcd.print(dht.readTemperature());
   lcd.setCursor(6, 1);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Dry Box On");
   lcd.setCursor(0, 1);
   lcd.print("Fans On");
   digitalWrite(intakefan, HIGH);
   digitalWrite(exfan, HIGH);
   digitalWrite(returnfan, HIGH);
   delay(2000);
   lcd.clear();
   lcd.print("Humidity");
   lcd.setCursor(0, 1);
   lcd.print(dht.readHumidity());
   lcd.setCursor(6, 1);
   lcd.print("%");
   delay(2000);
}

void dewPointLow(float t, float h) {
   digitalWrite(humidv, HIGH);
   digitalWrite(dryv, LOW);
   digitalWrite(exv, HIGH);
   digitalWrite(returnfan, LOW);
   digitalWrite(returnv, LOW);
   lcd.print("Dew point LOW");
   lcd.setCursor(0,1);
   lcd.print(dewPoint(t, h));
   lcd.setCursor(6,1);
   lcd.print("c");
   delay(2000);
   digitalWrite(intakefan, HIGH);
   digitalWrite(exfan, HIGH);
   lcd.clear();
   lcd.print("Humid Box On");
   lcd.setCursor(0, 1);
   lcd.print("Fans On");
   delay(2000);
   lcd.clear();
   lcd.print("Dew Point Low");
   lcd.setCursor(0, 1);
   lcd.print(dewPoint(t, h));
   lcd.setCursor(6, 1);
   lcd.print("c");
   delay(2000);
   lcd.clear();
   lcd.print("Temperature");
   lcd.setCursor(0, 1);
   lcd.print(dht.readTemperature());
   delay(2000);
   lcd.clear();
   lcd.print("Humidity");
   lcd.setCursor(0, 1);
   lcd.print(dht.readHumidity());
   lcd.setCursor(6, 1);
   lcd.print("%");
   lcd.clear();
}

this is what i have changed so far.

   currentMillis = millis();                   //get the current "time" (actually the number of milliseconds since the program started)
   if (currentMillis - startMillis > period) { //test greater than period
      cycle = !cycle;                          // switch to alternate 4 day cycle
      startMillis = currentMillis;
      if(( cycle ) || (digitalRead(cyclereset, HIGH)); {
         lowDewPoint = 10.5;
         highDewPoint = 11.5;
      } else {
         lowDewPoint = 11.5;
         highDewPoint = 12.5;
      }
   }

Use bool variable that stay true at start of program. Set it false at changing the code. Do not change the code, if variable is false.

@matt82060 ,

Your two or more topics on the same or similar subject have been merged.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

sorry, deleted the other one accidently so did it again

I think you misunderstood me, you created a new topic End millis with push button? , which seems to me to be just a continuation (if not a repeat) of this topic. I merged the new topic into this one. I also saw the one you deleted, but there's no problem with that as you deleted it for whatever reason, it doesn't matter.

here's a different approach that avoids much of the redundant code

uncomment the lines for hour/days that accelerate the processing in order to test within a minute or so

# include <Wire.h>
# include <LiquidCrystal_I2C.h>
# include <DHT.h>

const byte PinDHTpwr = 12;
const byte PinFridge = 13;
                //    dryv exfan exv humidv intakefan returnfan returnv
const byte Pins [] = {   4,    5, 6,      3,        2,        7,      8 };


// -----------------------------------------------------------------------------
#define DHTPIN 11  // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11  // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht (DHTPIN, DHTTYPE);

LiquidCrystal_I2C lcd (0x27, 16, 2);  // LCD address 0x27 for a 16x2 display

// -------------------------------------

const int  Npins = sizeof (Pins);
const byte Settings [][Npins] = {
 //    dryv exfan   exv humidv intakefan returnfan returnv
    {   LOW, HIGH, HIGH,  HIGH,    HIGH,       LOW,    LOW }, // <
    {   LOW,  LOW,  LOW,   LOW,     LOW,       LOW,    LOW },
    {  HIGH, HIGH, HIGH,   LOW,    HIGH,      HIGH,   HIGH }, // >
};
int state = 1;

float humidity;
float tempC;
float tempF;
float dewPt;
float heatIdx;
float hiDegC;

const float  DewPtTarget [] = { 12, 11 };
int    targIdx = 0;

unsigned long msec0;

const int MsecTic = 2000;
int tic;
int hour;
int day;

int displayIdx;

// -----------------------------------------------------------------------------
void loop ()
{
    unsigned long msec = millis ();

    // just return if < 2 sec
    if (msec < msec0)
        return;

    msec0 += MsecTic;

    // track time
    tic++;
 // hour = tic / (3600 / MsecTic);
 // day  = hour / 24;
    hour = tic;
    day  = hour;                    // 1 day = 1 tics;

    targIdx = (day / 4) % 2;

    Serial.print   ("\n            day ");
    Serial.print   (day);
    Serial.print   (", idx ");
    Serial.print   (targIdx);
    Serial.println ();

    // regulate temperature
    if (tempF < 19)
        digitalWrite (PinFridge, LOW);
    else if (tempF > 21)
        digitalWrite (PinFridge, HIGH);

    // process DHT
    if (readSensors ())
        return;             // fault

    if      ((dewPt - DewPtTarget [targIdx]) < 0.5)
        state = 0;
    else if ((dewPt - DewPtTarget [targIdx]) > 0.5)
        state = 2;
    else
        state = 1;

    setPins (state);

    // update display
    switch (displayIdx) {
    case 0:
        switch (state) {
        case 0:
            display ("Dew point LOW",  DewPtTarget [targIdx], "C");
            break;

        case 1:
            display ("Dew point OK",   DewPtTarget [targIdx], "C");
            break;

        case 2:
            display ("Dew point HIGH", DewPtTarget [targIdx], "C");
            break;

        default:
            display ("Unknown state", state, "x");
            break;
        }
        displayIdx++;
        break;

    case 1:
        display ("Temperature", tempC, "C");
        displayIdx++;
        break;

    case 2:
        display ("Humidity", humidity, "%");
        displayIdx = 0;
        break;
    }
}

// -----------------------------------------------------------------------------
void
display (
    const char *text,
    float       val,
    const char *suffix )
{
    lcd.clear     ();
    lcd.print     (text);
    lcd.setCursor (0, 1);
    lcd.print     (val);
    lcd.setCursor (5, 0);
    lcd.print     (suffix);
}

// ---------------------------------------------------------
int
readSensors ()
{
    humidity = dht.readHumidity ();
    tempC    = dht.readTemperature ();
    tempF    = dht.readTemperature (true);

    dewPt    = dewPoint (tempC, humidity);  // Dew Point for setting pins high
    heatIdx  = dht.computeHeatIndex (tempF, humidity);
    hiDegC   = dht.convertFtoC (heatIdx);

    // Check if any reads failed and exit early (to try again).
    if (isnan(humidity) || isnan(tempC) || isnan(tempF)) {
        Serial.println ("Failed to read from DHT sensor!");
        lcd.clear ();
        lcd.print ("Failed to read from DHT sensor!");

        return 1;       // fault
    }

    return 0;
}

// ---------------------------------------------------------
void setPins (
    int  idx )
{
    for (int n = 0; n < Npins; n++)
        digitalWrite (Pins [n], Settings [state][idx]);
}

// -----------------------------------------------------------------------------
double dewPoint (double celsius, double humidity) {
    // (1) Saturation Vapor Pressure = ESGG(T)
    double RATIO = 373.15 / (273.15 + celsius);
    double RHS = -7.90298 * (RATIO - 1);
    RHS += 5.02808 * log10 (RATIO);
    RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / RATIO))) - 1);
    RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1);
    RHS += log10 (1013.246);

    // factor -3 is to adjust units - Vapor Pressure SVP * humidity
    double VP = pow (10, RHS - 3) * humidity;

    // (2) DEWPOINT = F(Vapor Pressure)
    double T = log (VP / 0.61078);  // temp var
    return (241.88 * T) / (17.558 - T);
}

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

    pinMode      (PinDHTpwr, OUTPUT);
    digitalWrite (PinDHTpwr, HIGH);
    pinMode      (PinFridge, OUTPUT);
    digitalWrite (PinFridge, LOW);

    for (int n = 0; n < Npins; n++)
        pinMode (Pins [n], OUTPUT);
    state = 1;
    setPins (state);


    Serial.begin (9600);
    lcd.init ();       // Initialize the LCD
    lcd.backlight ();  // Turn on the backlight
    lcd.clear ();      // Clear the LCD screen

    lcd.setCursor (3, 0);
    lcd.print ("The Green");
    lcd.setCursor (4, 1);
    lcd.print ("Ninja");
    delay (2000);  // Display the startup message for 2 seconds

    lcd.clear ();
    dht.begin ();
}
1 Like

Well this way of saying it is - more or less a misunderstanding of

  • what code is itself
    and
  • what code-execution is

Whenever you uploaded any kind of code into your microcontroller
this code itself

STAYS THE SAME CODE

totally regardless of what your code looks like. Could be a few lines or 10000 lines
and could contain whatever youl like.

This code stays the absolutely and exact the same code
until you upload a new code.

What can change is which parts of the code were really executed.

in the following code-example the line with

Serial.println("This will NEVER NEVER be printed");

is part of the code but
will never ever be printed because the code-execution is conditional to a condition that never can become true

if ( false ) {
  Serial.println("This will NEVER NEVER be printed");
}

You can use boolean variables to make code-execution dependant on a condition

boolean first4Days;
boolean second4Days;
boolean third4Days;
if (first4Days == true) {
  // put all code that shall be executed in the first 4 days here
}

if (second4Days == true) {
  // put all code that shall be executed in the second 4 days here
}

if (third4Days == true) {
  // put all code that shall be executed in the THIRD 4 days here
}

trying to reset the function millis() is a really silly and stupid idea.
You don't need to. All you need to do is updating timing variables.
And by using a function this updating can be done automatically by and inside the function.

So here is a demo-code. Full code posted below.
For explaining parts of the code are posted first.
The code is structured into multiple functions where each part of the code does
one thing

the functions have self-explaining names. This means these function-calls inside loop() give an overview about what the code is doing

The code simply prints to the serial monitor and switches on / off two LEDs where the LEDs represent / indicate

  • code part 1 executing first 4 days
  • code part 2 executing second 4 days

function loop()

void loop() {
  // check if 4 days of time have passed by
  if ( TimePeriodIsOver(my4DayTimer, myInterval) == true ) {
    // if REALLY 4 days of time have passed by
    flip_between_First_and_Second();
  }

  // check if boolean variable with name "first4Days"  is true
  if (first4Days == true) {
    printFirst_4_days_message(); // does what the function name says
  }

  // check if boolean variable with name "second4Days"  is true
  if (second4Days == true) {
    printSecond_4_days_message(); // does what the function name says
  }

  printDaysPassedBy(); // does what the functions name says
}

WOKWI-Simulation

complete demo-code

// https://forum.arduino.cc/t/resetting-millis/1213723/19
// https://wokwi.com/projects/387534707798036481

const byte led1Pin = 12;
const byte led2Pin =  2;

unsigned long my4DayTimer;
unsigned long myPrintInfoTimer;
//unsigned long myShortTimer;
const unsigned long myInterval = 4000;

boolean first4Days;
boolean second4Days;

void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);

  my4DayTimer = millis();
  myPrintInfoTimer = millis();
  first4Days = true;
  second4Days = false;
}

void loop() {

  // check if 4 days of time have passed by
  if ( TimePeriodIsOver(my4DayTimer, myInterval) == true ) {
    // if REALLY 4 days of time have passed by
    flip_between_First_and_Second();
  }

  // check if boolean variable with name "first4Days"  is true
  if (first4Days == true) {
    printFirst_4_days_message(); // does what the function name says
  }

  // check if boolean variable with name "second4Days"  is true
  if (second4Days == true) {
    printSecond_4_days_message(); // does what the function name says
  }

  printDaysPassedBy(); // does what the functions name says

}



// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long & startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}


void printDaysPassedBy() {

  static unsigned long myPrintInfoTimer;

  if ( TimePeriodIsOver(myPrintInfoTimer, 1000) ) {
    Serial.print("-day");
    Serial.print( ( millis() - my4DayTimer) / 1000);
  }
}


void printFirst_4_days_message() {
  static unsigned long myShortTimer;

  if ( TimePeriodIsOver(myShortTimer, 500) == true) {
    Serial.print("  1st");
    digitalWrite(led1Pin, !digitalRead(led1Pin)); // invert LOW/HIGH by using the not-operator
  }
}


void printSecond_4_days_message() {
  static unsigned long myShortTimer;

  if ( TimePeriodIsOver(myShortTimer, 500) == true) {
    Serial.print("  2nd");
    digitalWrite(led2Pin, !digitalRead(led2Pin)); // invert LOW/HIGH by using the not-operator
  }
}


void flip_between_First_and_Second() {
  if (first4Days == true) {
    first4Days  = false;
    second4Days = true;
    //Serial.println("change to SECOND 4 days code");
    Serial.println();
    digitalWrite(led1Pin, LOW);
  }
  else {
    first4Days  = true;
    second4Days = false;
    //Serial.println("change to first 4 days code");
    Serial.println();
    digitalWrite(led2Pin, LOW);
  }
}

best regards Stefan

1 Like