Reptile Mister Programming for Newbie

Hello all,
I do not know where to turn at this point. I have wanted to do this project for a couple years now and have watched countless videos, googled and attempted to learn to write the appropriate code but I am struggling. I want to build a mister for a reptile enclosure but am completely stuck on the Arduino code. I am really hoping someone can point me in the right direction. I don't think it's overly complicated but for someone with no experience in this it's been a big challenge. I really want to build this myself and not buy one, the only thing holding this up is this programming.

Here is what I want to do:
I want to program the Arduino to control a pump by way of a relay. The pump will pump water through a misting tip to mist the reptile cage.
I'm looking to have a display, 4 buttons to program and a relay that runs the pump.

My plan for the buttons is this:
1-Will scroll through the 3 options in a menu
2 & 3 will set the values for those options, one goes up the other goes down.
4- The final button will start the program.

The 3 screens with settings are:
1- Delay (in hours) - How much time before the first time the relay is triggered leading to a misting.
2-Frequency of misting(in hours) - After the delay timer hits 0 and mists this timer starts. When it reaches 0 it activates the relay leading to another misting then starts counting down again in a loop. i.e. Every 4 hours mist.
3- How long to mist for (In seconds)- How long to leave the relay open for misting into the cage before stopping.

Once those three values are set the 4th button is pressed and the program runs and the Delay timer starts. Then the program will run until the power is turned off.

I hope that was clear and there are some kind people out there to help me figure out what to do. Thank you all!

The first thing you need to do is go through the examples in the IDE.

After that, study/master BWD timers and State Machine programming.

Suggest you also draw a proposed schematic that matches your requirements.


How much does a ready made unit cost ?


Have you looked at using an ultrasonic mister control ?

What relay do you have?

What display are you using?

What buttons or switches?

How are they wired to your Arduino, and what kind of Arduino board are you using?

What at all have you tried for the only thing holding you up?

a7

The units are in the neighborhood of $50, I admit that is the easiest route by far but there is something to 3D printing parts and programming something like this yourself. I literally have the rest figured out even the wiring for this, it's just the writing the program. I have not looked into the ultrasonic mister control or are even familiar with it. I will check it out though.

IMO, an ultrasonic fogger/mister sitting in distilled water is what should be used for this.

No pump, no relay.

Hey alto777, I should have thought to include these details:

The Display is this: Amazon.com

The Relay is this:

The Arduino is the nano, this:

The buttons are just the black standard buttons that you can put into a breadboard. As far as the wiring I have been using the Tinkercad circuit program to try and design this virtually before actually wiring it all together. Attached is a snip of the diagram as wired. Tinkercad doesn't have the display I have so I figured I'll just have to modify the code appropriately though.

As far as trying, I've drawn up designs for the what the printed enclosure to hold the electronics will look like, purchased everything needed, and have just been trying to get the code written.

i

THX.

Looks like you approach things in a slightly different direction than I. Do.

A few observations.

The Nano Every is just enough different so it may make you do a little extra work from time to time, no show stoppers I don’t think, but an occasional you’ll need to do some digging, one hopes minor.

The nine volt battery may have been all tinkercod had available to represent the power supply, but a smoke detector 9 volt rectangular battery will be almost worthless if it is asked to provide any larger current as the misting device may require, or even the smaller current by the lower powered items for very long.

The usual practice is to provide power to the Arduino, and whatever voltage is required to the other components directly, that is to say not using the 5 volt output pin on the UNO or other Arduino board as a power supply.

Anything over 5 volts fed to the UNO is wasted in heat; it is preferred to use 5 volts, either a 5 volt power supply or by use of a regulator to make 5 volts out of 9 or 12 that you have plenty of. A step-down or “buck” regulator is efficient and effective.

But the largest part of all is the software, so yes, you will have to start where we all did… get the Nano or whatever to blink an LED, respond to switches &c.

Start or keep reading examples and trying them out.

Develop each capability (display, buttons, misting) separate ly, and only when each section works well with your code start on any grand combining of the pieces.

Usually a piece of hardware meant for the Arduino has lotsa ppl already doing things with it, so find working examples and study them, try them, tinker with them and so forth.

Put aside all fantasy about what kind of box this goes in and so forth. It won’t be for awhile that putting things in their final physical relationships to each other won’t be a waste of time or at least a distraction. I speak as someone with large fingers…

You ve bitten off quite a mouthful, so lastly I recommend that you stay calm and give up the idea that this will be finished by Christmas Valentine’s Day.

Also, even hand drawn “real” schematics will win more attention around here than any tinkercod or Fritzling diagrams - they are not very good at the most important thing a schematic should communicate - how the parts are wired together. I recommend getting to know a bit about how real schematic diagrams are used, there’s prolly a crap-ton of tuts online for basic schematic literacy.

I’ve recently had the Bing viruus, so I can tell you that it is deficient and no match for Google, so when you google, I suggest Googling.

HTH and we here for as fine a stepping through this as you may need.

a7

Is it safe to use an ultrasonic mister with a reptile? You need to be sure it is above their hearing range so you don't harm their hearing.

I appreciate the write up, alto. To your point about the 9V battery, it was just because that was the easiest thing tinkercad had to represent a power source for the pump, your right about that. I intend to run this entire setup on a 18650 battery because I want it portable. I have sourced a pump that works at that voltage and a charge discharge board for the battery to protect it.

I have been able to do some basic stuff like you mentioned but I tend to get lost when it gets bigger.

I have actually have been trying to develop a code for each purpose as you've mentioned and I've had moderate success with it. For example, I have gotten a program to work as a menu that uses the buttons. It allowed you to move between the three categories I listed above and select a time for the hours and seconds. But it doesn't relate to a timer in anyway and that's the hard part.

I did find a timer code where the value is set in the arduino sketch and once it hit zeto that triggered the pump to mist. I'm struggling to link the two let alone in a manner that I laid out in my original post. That is what I've been doing mostly, piecing out the different sketches and then every time I try to bring two codes together I can't get anywhere because I get lost.

I have only drawn the physical design out as an idea but put it on the back burner until the coding is done. I'll look into some examples of schematics and starting learning those as well. I do always use google as well.

First, if you haven't yet done any breadboarding wire the pushbuttons according to S3 below and specify INPUT_PULLUP in Setup() when you do your pinMode().

Second, debounce ALL the switches before using their status.

Third, use the change of state of the buttons and not the current status.

See the first five demos in: IDE/file/examples/digital.

Do not attempt to construct the whole program at one go.  Start with just detecting one button and using it to increment a counter.  Serial.print the counter value to verify you're only getting one sense per button press.

Then, modify the code to reset the counter to zero when a preset (three in your case) is reached.  The counter value can be used to select which menu option is active.  Add a small piece at at time and prove it does what you want before moving on.

What display will you use?

It may not be important and you hardly need another plateful, but an RTC “real time clock” module would give you accurate timing related to the actual time of day, so every four hours could be 2, 6, 10 o’clock and so forth. They are inexpensive and fairly easy to work with, good libraries exist and many examples code.

And if you are using a battery, you will need to figure out how to get the entire system to go into a low power mode between mistings… here again an RTC can play a part.

But you can leave off that entire branch of R&D and just get a mains powered version functioning.

Then mains power with the RTC perhaps, then sleeping between mist times.

If sleep is going to be needed, there may be easier Arduino to start with than the Nano Every, which I use but for which I have not looked into extreme or even not extreme reduced power operation.

a7

Thank you all again. I'm going to take a little time and see where I can get this weekend with these suggestions. I hadn't even considered a low power mode between activities but that makes perfect sense!

When the time comes, this is where you want to go for the skinny on low power:

It may seem like a slog, but he lays out everything there is and provides full examples that can be cut. pasted and experimented with.

Warning: low power can be addictive. Once you are seeing currents like 125 uA it is hard not to want to do everything possible to reduce that to nearly not measurabel.

a7

I'm not sure if I should start a new post or continue this discussion here but here it goes:

I have a working code based on this post, it does what I want but I have a small issue with it that I don't know how to fix. Basically, when the timer is set it is adds seconds to the timer that aren't called for. For Example: I set it for 1 minute and it goes to 1 minute and 3 seconds, the more time I add the more extra seconds are added.

Second question: I did testing using an Arduino Uno but wanted to use an Arduino Nano Every for the final project, the issue is I have been told they aren't compatible to exchange codes? Is there a simple solution to allow this to work with the Every without rewriting the whole code? I've attached it below

Blockquote

#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif9pt7b.h>

#define Enter_button 2
#define Back_button 3
#define Upp_button 4
#define Down_button 5

#define Pump_pin 11


#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32



Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);



struct Time_Settings {
  uint8_t set_flag = 0;
  unsigned long Startup_Delay_value = 0;
  unsigned long Pump_Interval_value = 0;
  unsigned long Pump_Duration_value = 0;
} timers;

enum startup_setting {
  last_config = 0,
  change_setting = 1
};

enum timer_setting {
  startup_delay = 0,
  pump_interval = 1,
  pump_duration = 2,
  save_and_exit = 3
};
enum setting {
  startup_settings = 0,
  timer_settings = 1,
  time_settings = 2
};
enum time_setting {
  hour = 0,
  minute = 1,
  second = 2
};
enum system_stage {
  settings_stage = 0,
  info_stage = 1,
  running_stage = 2
};

volatile uint8_t delay_Interval_h = 0;
volatile uint8_t delay_Interval_m = 0;
volatile uint8_t delay_Interval_s = 0;
volatile uint8_t Pump_Interval_h = 0;
volatile uint8_t Pump_Interval_m = 0;
volatile uint8_t Pump_Interval_s = 0;
volatile uint8_t Pump_Duration_h = 0;
volatile uint8_t Pump_Duration_m = 0;
volatile uint8_t Pump_Duration_s = 0;

volatile byte startup_menu_level = 0;
volatile byte timer_menu_level = 0;
volatile byte timer_submenu_level = 0;
volatile byte menu_level = 0;

volatile unsigned long Startup_Delay_value_copy = 0;
volatile unsigned long Pump_Interval_value_copy = 0;
volatile unsigned long Pump_Duration_value_copy = 0;

volatile uint8_t system_mode = 0;
volatile byte intervalCountDown_flag = 0;
volatile byte pumping_flag = 0;
volatile byte display_flag = 0;
volatile byte setting_flag = 0;
volatile byte delay_flag = 0;

// variables to hold old state of buttons
byte Upp_button_OldState = LOW;
byte Down_button_OldState = LOW;

// variables to hold new state of buttons
byte Upp_button_NewState = LOW;
byte Down_button_NewState = LOW;

ISR(TIMER1_COMPA_vect) {
  if (!delay_flag) {
    Startup_Delay_value_copy--;
    if (Startup_Delay_value_copy <= 0) {
      intervalCountDown_flag = 1;
      delay_flag = 1;
    }
  }
  if (delay_flag && intervalCountDown_flag) {
    Pump_Interval_value_copy--;
    if (Pump_Interval_value_copy <= 0) {
      Pump_Interval_value_copy = timers.Pump_Interval_value;
      intervalCountDown_flag = 0;
      pumping_flag = 1;
      display_flag = 1;
      digitalWrite(Pump_pin, LOW);
    }
  }
  if (delay_flag && pumping_flag) {
    Pump_Duration_value_copy--;
    if (Pump_Duration_value_copy <= 0) {
      Pump_Duration_value_copy = timers.Pump_Duration_value;
      pumping_flag = 0;
      intervalCountDown_flag = 1;
      display_flag = 1;
      digitalWrite(Pump_pin, HIGH);
    }
  }
}
void Config_interrupt(void) {
  //set timer1 interrupt at 1Hz
  cli();//stop interrupts
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei();//allow interrupts
}
void setup() {
  Serial.begin(115200);

  pinMode(Enter_button, INPUT_PULLUP);
  pinMode(Upp_button, INPUT_PULLUP);
  pinMode(Down_button, INPUT_PULLUP);
  pinMode(Back_button, INPUT_PULLUP);
  pinMode(Pump_pin, OUTPUT);
  digitalWrite(Pump_pin, HIGH);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }

  Config_interrupt();
  attachInterrupt(digitalPinToInterrupt(Enter_button), Enter_Function , FALLING);
  attachInterrupt(digitalPinToInterrupt(Back_button), Back_Function , FALLING);

  //read initial state of buttons
  Upp_button_OldState = digitalRead(Upp_button);
  Down_button_OldState = digitalRead(Down_button);

  //load timer settings
  Load_settings();
  if (timers.set_flag == 20)setting_flag = 1;
  else {
    setting_flag = 0;
    Startup_Delay_value_copy = 100;
  }

  //display welcome message
  WelcomeScreen();

  startup(startup_menu_level);
}
void loop() {
  if (system_mode != running_stage) {
    if (system_mode == info_stage) {
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setTextSize(1);
      display.setCursor(0, 10);
      display.print("No setting save yet");
      display.display();
      delay(1);
    }
    else {
      readButtons();
      switch (menu_level) {
        case startup_settings:
          startup(startup_menu_level);
          break;
        case timer_settings:
          Menu_settings(timer_menu_level);
          break;
        case time_settings:
          if (timer_menu_level == startup_delay) {
            set_startup_timer(timer_submenu_level);
          }
          if (timer_menu_level == pump_interval) {
            set_interval_timer(timer_submenu_level);
          }
          if (timer_menu_level == pump_duration) {
            set_duration_timer(timer_submenu_level);
          }
          if (timer_menu_level == save_and_exit) {
            menu_level = startup_settings;
            Save_and_Exit();
          }
          break;
      }
    }
  }
  else {
    if (!delay_flag) {
      compute_TimeParameters();
      display.clearDisplay();
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(10, 1);            // Start at top-left corner
      display.println(F("Delay Countdown"));
      display.setTextSize(2);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(30, 16);            // Start at top-left corner
      display.print(delay_Interval_h);
      display.print(F(":"));
      display.print(delay_Interval_m);
      display.print(F(":"));
      display.print(delay_Interval_s);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
    }
    if (delay_flag && pumping_flag) {
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setTextSize(1);
      display.setCursor(22, 10);
      display.print("Pumping...");
      display.display();
      delay(1);
      display_flag = 0;
    }
    if (delay_flag && intervalCountDown_flag) {
      compute_TimeParameters();
      display.clearDisplay();
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(10, 1);            // Start at top-left corner
      display.println(F("Will start Pump in"));
      display.setTextSize(2);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(30, 16);            // Start at top-left corner
      display.print(Pump_Interval_h);
      display.print(F(":"));
      display.print(Pump_Interval_m);
      display.print(F(":"));
      display.print(Pump_Interval_s);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      display_flag = 0;
    }
  }


}
void Save_and_Exit() {
  copy_variables_to_timers();
  EEPROM.put(0, timers);
}
void Load_settings() {
  EEPROM.get(0, timers);
  copy_timers_to_variables();
}
void readButtons() {
  Upp_button_NewState = digitalRead(Upp_button);
  Down_button_NewState = digitalRead(Down_button);

  //check if there is change of state from low to high for button 1
  if (Upp_button_NewState != Upp_button_OldState && Upp_button_OldState) {
    switch (menu_level) {
      case startup_settings:
        startup_menu_level = 0;
        startup(startup_menu_level);
        break;
      case timer_settings:
        if (timer_menu_level > 0)timer_menu_level--;
        break;
      case time_settings:
        switch (timer_menu_level) {
          case startup_delay:
            if (timer_submenu_level == hour)Startup_Delay_value_copy += 3600;
            if (timer_submenu_level == minute)Startup_Delay_value_copy += 60;
            //copy_timers_to_variables();
            set_startup_timer(timer_submenu_level);
            break;
          case pump_interval:
            if (timer_submenu_level == hour)Pump_Interval_value_copy += 3600;
            if (timer_submenu_level == minute)Pump_Interval_value_copy += 60;
            //copy_timers_to_variables();
            set_interval_timer(timer_submenu_level);
            break;
          case pump_duration:
            //if (timer_submenu_level == hour)Pump_Duration_value_copy += 3600;
            //if (timer_submenu_level == minute)Pump_Duration_value_copy += 60;
            if (timer_submenu_level == 0)Pump_Duration_value_copy += 1;
            //copy_timers_to_variables();
            set_duration_timer(timer_submenu_level);
            break;
          default: break;
        }
        break;
      default: break;
    }
  }

  //check if there is change of state from low to high for button 2
  if (Down_button_NewState != Down_button_OldState && Down_button_OldState) {
    switch (menu_level) {
      case startup_settings:
        startup_menu_level = 1;
        startup(startup_menu_level);
        break;
      case timer_settings:
        if (timer_menu_level < 3)timer_menu_level++;
        break;
      case time_settings:
        switch (timer_menu_level) {
          case startup_delay:
            if (timer_submenu_level == hour && Startup_Delay_value_copy >= 3600)Startup_Delay_value_copy -= 3600;
            if (timer_submenu_level == minute && Startup_Delay_value_copy >= 60)Startup_Delay_value_copy -= 60;
            //copy_timers_to_variables();
            set_startup_timer(timer_submenu_level);
            break;
          case pump_interval:
            if (timer_submenu_level == hour && Pump_Interval_value_copy >= 3600)Pump_Interval_value_copy -= 3600;
            if (timer_submenu_level == minute && Pump_Interval_value_copy >= 60)Pump_Interval_value_copy -= 60;
            //copy_timers_to_variables();
            set_interval_timer(timer_submenu_level);
            break;
          case pump_duration:
            //if (timer_submenu_level == hour && Pump_Duration_value_copy >= 3600)Pump_Duration_value_copy -= 3600;
            //if (timer_submenu_level == minute && Pump_Duration_value_copy >= 60)Pump_Duration_value_copy -= 60;
            if (timer_submenu_level == 0 && Pump_Duration_value_copy >= 1)Pump_Duration_value_copy -= 1;
            //copy_timers_to_variables();
            set_duration_timer(timer_submenu_level);
            break;
          default: break;
        }
        break;
      default: break;
    }


  }
  Upp_button_OldState = Upp_button_NewState;
  Down_button_OldState = Down_button_NewState;
  delay(100);
}
void copy_timers_to_variables() {
  Startup_Delay_value_copy = timers.Startup_Delay_value;
  Pump_Interval_value_copy = timers.Pump_Interval_value;
  Pump_Duration_value_copy = timers.Pump_Duration_value;
}
void copy_variables_to_timers() {
  timers.set_flag = 20;
  timers.Startup_Delay_value = Startup_Delay_value_copy;
  timers.Pump_Interval_value = Pump_Interval_value_copy ;
  timers.Pump_Duration_value = Pump_Duration_value_copy;
}
void compute_TimeParameters() {
  delay_Interval_h = Startup_Delay_value_copy / 3600;
  delay_Interval_m = ((Startup_Delay_value_copy - ((int)(Startup_Delay_value_copy / 3600) * 3600)) / 60);
  delay_Interval_s = ((Startup_Delay_value_copy - ((int)(Startup_Delay_value_copy / 3600) * 3600)) % 60);
  Pump_Interval_h = Pump_Interval_value_copy / 3600;
  Pump_Interval_m =  ((Pump_Interval_value_copy - ((int)(Pump_Interval_value_copy / 3600) * 3600)) / 60);
  Pump_Interval_s =  ((Pump_Interval_value_copy - ((int)(Pump_Interval_value_copy / 3600) * 3600)) % 60);
  Pump_Duration_h = Pump_Duration_value_copy / 3600;
  Pump_Duration_m = ((Pump_Duration_value_copy - ((int)(Pump_Duration_value_copy / 3600) * 3600)) / 60);
  Pump_Duration_s = ((Pump_Duration_value_copy - ((int)(Pump_Duration_value_copy / 3600) * 3600)) % 60);
}

void Enter_Function() {
  switch (menu_level) {
    case startup_settings:
      if (startup_menu_level == last_config) {
        if (setting_flag) {
          system_mode = running_stage;
          delay_flag = 0;
          intervalCountDown_flag = 1;
        }
        else  system_mode = info_stage;
      }
      if (startup_menu_level == change_setting) {
        menu_level = timer_settings;
        system_mode = settings_stage;
      }
      break;
    case timer_settings:
      menu_level = time_settings;
      break;
    case time_settings:
      timer_submenu_level++;
      if (timer_submenu_level == 2 && (timer_menu_level == 0 || timer_menu_level == 1)) {
        menu_level = timer_settings;
        timer_submenu_level = 0;
      }
      if (timer_submenu_level == 1 && timer_menu_level == 2) {
        menu_level = timer_settings;
        timer_submenu_level = 0;
      }
      break;
    default: break;
  }

}
void Back_Function() {
  switch (menu_level) {
    case timer_settings:
      menu_level = startup_settings;
      break;
    case time_settings:
      menu_level = timer_settings;
      break;
    default: break;
  }
  if (system_mode == info_stage) {
    system_mode = settings_stage;
  }
}
void WelcomeScreen(void) {
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(22, 10);
  display.print("WELCOME");
  display.display();
  delay(2000);
}
void startup(int option) {
  display.clearDisplay();
  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(8, 4);            // Start at top-left corner
  display.println(F("Last save settings"));
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(8, 18);            // Start at top-left corner
  display.println(F("New settings"));


  display.setTextColor(SSD1306_WHITE);        // Draw white text
  switch (option) {
    case 0:
      display.drawRect(5, 1, display.width() - 10, 13, SSD1306_WHITE);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    case 1:
      display.drawRect(5, 15, display.width() - 10, 13, SSD1306_WHITE);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    default:
      break;
  }
  display.display();
}
void Menu_settings(int option) {
  display.clearDisplay();
  switch (option) {
    case 0:
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(8, 4);            // Start at top-left corner
      display.println(F("Delay Timer"));
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(8, 18);            // Start at top-left corner
      display.println(F("Interval Timer"));
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.drawRect(5, 1, display.width() - 40, 13, SSD1306_WHITE);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    case 1:
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(8, 4);            // Start at top-left corner
      display.println(F("Delay Timer"));
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(8, 18);            // Start at top-left corner
      display.println(F("Interval Timer"));
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.drawRect(5, 15, display.width() - 40, 13, SSD1306_WHITE);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    case 2:
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(8, 4);            // Start at top-left corner
      display.println(F("Interval Timer"));
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(8, 18);            // Start at top-left corner
      display.println(F("Pump Timer"));
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.drawRect(5, 15, display.width() - 40, 13, SSD1306_WHITE);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    case 3:
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(8, 4);            // Start at top-left corner
      display.println(F("Pump Timer"));
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(8, 18);            // Start at top-left corner
      display.println(F("Save and exit"));
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.drawRect(5, 15, display.width() - 40, 13, SSD1306_WHITE);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    default:
      break;
  }
  display.display();
  //delay(1000);
}
void set_startup_timer(int setting_level) {
  display.clearDisplay();
  compute_TimeParameters();
  switch (setting_level) {
    case 0:
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(36, 1);            // Start at top-left corner
      display.println(F("Delay Hour"));
      display.setTextSize(2);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(56, 16);            // Start at top-left corner
      display.println(delay_Interval_h);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    case 1:
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(36, 1);            // Start at top-left corner
      display.println(F("Delay minute"));
      display.setTextSize(2);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(56, 16);            // Start at top-left corner
      display.println(delay_Interval_m);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    default:
      break;
  }
  display.display();
}
void set_interval_timer(int setting_level) {
  compute_TimeParameters();
  display.clearDisplay();
  switch (setting_level) {
    case 0:
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(36, 1);            // Start at top-left corner
      display.println(F("Interval Hour"));
      display.setTextSize(2);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(56, 16);            // Start at top-left corner
      display.println(Pump_Interval_h);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    case 1:
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(36, 1);            // Start at top-left corner
      display.println(F("Interval minute"));
      display.setTextSize(2);             // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE);        // Draw white text
      display.setCursor(56, 16);            // Start at top-left corner
      display.println(Pump_Interval_m);
      display.display(); // Update screen with each newly-drawn rectangle
      delay(1);
      break;
    default:
      break;
  }
  display.display();
}
void set_duration_timer(int setting_level) {
  compute_TimeParameters();
  display.clearDisplay();
  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(36, 1);            // Start at top-left corner
  display.println(F("Pump time(s)"));
  display.setTextSize(2);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(56, 16);            // Start at top-left corner
  display.println(Pump_Duration_s);
  display.display(); // Update screen with each newly-drawn rectangle
  delay(1);
  display.display();
}

Sprayer.ino (21.3 KB)

Oh, that's easy.

If you continue the discussion here, it makes it easier for the moderators as they do not have to move your new post back onto the end of the old one. :sunglasses:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.