Hi all!
I'm trying to write a code for an irrigation system, but I'm having trouble changing the set value for comparison to the humidity sensor value.
I have the lcd displaying the actual values from the humidity sensors. This value is compared with the set humidity, and if sensorvalue > sethumidity, a water pump is activated. I would like to be able to change the set humidity with the buttons from the lcd keypad shield. The code that I have so far is:
// LcdKeypad - Version: Latest
#include <EEPROM.h>
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define WATERPIN3 3
#define WATERPIN2 2
#define READSOILPIN A1
#define READSOILPIN2 A2
// higher number is more dry
#define WATERDELAY 5000
#define WATERPOSTDELAY 5000
int lcd_key = 0;
int adc_key_in = 0;
int MAXDRY1;
int MAXDRY2;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int read_LCD_buttons(){ // read the buttons
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
// We make this the 1st option for speed reasons since it will be the most likely result
if (adc_key_in > 1000) return btnNONE;
// For V1.1 us this threshold
/* if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;
*/
// For V1.0 comment the other threshold and use the one below:
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE; // when all others fail, return this.
}
void setup()
{
lcd.begin(16, 2);// set up the LCD's number of columns and rows:
lcd.clear();
Serial.begin(9600);
pinMode(READSOILPIN, INPUT);
pinMode(READSOILPIN2, INPUT);
pinMode(WATERPIN3, OUTPUT);
pinMode(WATERPIN2, OUTPUT);
EEPROM.read (1);
EEPROM.read (2);
}
void loop()
{
int SensorValue1 = analogRead(READSOILPIN); //take a sample
int SensorValue2 = analogRead(READSOILPIN2); //take a sample
lcd.clear();
lcd.setCursor(0,0); // Sets the cursor to col 0 and row 0
lcd.print("Humedad:"); // Prints Sensor Val: to LCD
lcd.print(analogRead(READSOILPIN)); // Prints value on Potpin1 to LCD
lcd.print("/"); // Prints Sensor Val: to LCD
lcd.print(analogRead(READSOILPIN2)); // Prints value on Potpin1 to LCD
MAXDRY1 = EEPROM.read(1);
MAXDRY2 = EEPROM.read(2);
Serial.print(adc_key_in);
switch (lcd_key) {
lcd_key = read_LCD_buttons();
case btnLEFT:{
if (read_LCD_buttons == btnUP){
(MAXDRY1++);
}
else if (read_LCD_buttons == btnDOWN){
(MAXDRY1--);
}
case btnRIGHT: {
if (read_LCD_buttons == btnUP){
(MAXDRY2++);
}
else if (read_LCD_buttons == btnDOWN){
(MAXDRY2--);
}
}
}
}
if(SensorValue1 >= MAXDRY1)
{
// if the soil is too dry start watering for 3/4 a second then
// wait for 5 seconds before monitoring again
digitalWrite(WATERPIN3, HIGH);
delay(WATERDELAY);
digitalWrite(WATERPIN3, LOW);
delay(WATERPOSTDELAY);
}
if(SensorValue2 >= MAXDRY2)
{
// if the soil is too dry start watering for 3/4 a second then
// wait for 5 seconds before monitoring again
digitalWrite(WATERPIN2, HIGH);
delay(WATERDELAY);
digitalWrite(WATERPIN2, LOW);
delay(WATERPOSTDELAY);
}
EEPROM.write (1,MAXDRY1);
EEPROM.write (2,MAXDRY2);
lcd.setCursor(8,1);
lcd.print(MAXDRY1);
lcd.print(MAXDRY2);
}
Any help is greatly appreciated!
(Okay, I've added Code Tags for you - next time, use the </> button when you post. Moderator)
Thanks!
You are attempting to read one of two button to determine if the user wants to update the values of MAXDRY1 or MAXDRY2 respectively. In the next loop() iteration you attempt to determine whether the user wants to increment or decrement the chosen value by checking to see what buttons have been pressed. One problem is that you are immediately then losing the information that the user wants to update either MAXDRY1 or MAXDRY2.
With your button shield with all buttons being read by the same analog pin, and one button interferes with the results of another, your only hope is to set a status variable that user is in the process of updating MAXDRY1 or MAXDRY2. Then you can test for the up/down presses and increment/decrement the selected MAXDRYx variable. This status variable should be reset if there is no button activity for, say, 5 seconds.
There is another problem with your code.
You should not write to the EEPROM on every loop iteration. This has a limited maximum number of write operations before it fails.
How can I make so that when I press a button, it goes into a calibration mode (lcd.setcursor (0,0)) while still showing the values of the sensors (lcd.setcursor(0,1)).
Tavobachi:
How can I make so that when I press a button, it goes into a calibration mode (lcd.setcursor (0,0)) while still showing the values of the sensors (lcd.setcursor(0,1)).
As a first step, I'd create a function reading the keys, which acts similar to the Serial.read() function and either returns -1 (in case no button was pressed since last calling the function or in case of a state-change-detection occurs:
return 'S' for Select cbutton
return 'U' for Up button
return 'D' for Down button
return 'L for Left button
return''R' for Right button
The 1602 LCD has three cursor modes:
no visible cursor
blinking undersore cursor
-block cursor
For editing with the LCD Keypad shield, I'd possibly prefer the block cursor as an indication of the cursor position which can be edited at the moment.
I think, somewhere I should have an unused LCD Keypad Shield.
If you like, I could look after it, stack it on an UNO and develop soemething for "state-change-detection" of analog buttons and editing a humidity setpoint.
What do you actually need:
editing of a number with two digits and no decimals?
Or rather three digits with one decimal?
setpoint range from 10% up to 90% or what range do you need for editing?
Hi!
The option to set a value would be an integer, that would increase or decrease depending on which button is pressed. I think my main issue is that all the buttons use the same port (A0), I would have to make it so that when a btn is pressed it goes into a calibration mode, until another btn is pressed or a set time goes by. Then it goes back to showing the sensor values.
adc_key_in should be local to read_LCD_buttons(); no need to have it global lcd_key should be local to loop()
The below can be a framework that you can build on; it uses btnLeft to enter calibration mode and btnRight to terminate calibration mode.
// LcdKeypad - Version: Latest
#include <EEPROM.h>
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define MODE_RUN 0
#define MODE_CALIBRATE 1
#define WATERPIN3 3
#define WATERPIN2 2
#define READSOILPIN A1
#define READSOILPIN2 A2
// higher number is more dry
#define WATERDELAY 5000
#define WATERPOSTDELAY 5000
int MAXDRY1;
int MAXDRY2;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int read_LCD_buttons() // read the buttons
{
int adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
// We make this the 1st option for speed reasons since it will be the most likely result
if (adc_key_in > 1000) return btnNONE;
// For V1.0 comment the other threshold and use the one below:
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE; // when all others fail, return this.
}
void setup()
{
lcd.begin(16, 2);// set up the LCD's number of columns and rows:
lcd.clear();
Serial.begin(9600);
pinMode(READSOILPIN, INPUT);
pinMode(READSOILPIN2, INPUT);
pinMode(WATERPIN3, OUTPUT);
pinMode(WATERPIN2, OUTPUT);
EEPROM.read (1);
EEPROM.read (2);
}
void loop()
{
static int mode = MODE_RUN;
int lcd_key = read_LCD_buttons();
if (mode == MODE_RUN)
{
if (lcd_key == btnLEFT)
{
mode = MODE_CALIBRATE;
}
else
{
run(lcd_key);
}
}
else if (mode == MODE_CALIBRATE)
{
if (calibrate(lcd_key) == true)
{
mode = MODE_RUN;
}
}
}
/*
perform calibration
in:
button
returns:
true when calibration finished, else false
*/
bool calibrate(int btn)
{
if (btn == buttonRight)
{
// save value
...
...
// indicate calibration finished
return true;
}
// do increment/decrement
...
...
// indicate calibration still in progress
return false;
}
void run(int btn)
{
...
...
}
This is how I filled your template, but when I press the btnleft to go into calibration mode it only works sometimes the first time, and it doesn't work again. I removed the EEPROM to see if it would help, but it doesn't.
Please help !.
// LcdKeypad - Version: Latest
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define MODE_RUN 0
#define MODE_CALIBRATE 1
#define WATERPIN3 3
#define WATERPIN2 2
#define READSOILPIN A1
#define READSOILPIN2 A2
// higher number is more dry
#define WATERDELAY 5000
#define WATERPOSTDELAY 5000
int MAXDRY1;
int MAXDRY2;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int read_LCD_buttons() // read the buttons
{
int adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
// We make this the 1st option for speed reasons since it will be the most likely result
if (adc_key_in > 1000) return btnNONE;
// For V1.0 comment the other threshold and use the one below:
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE; // when all others fail, return this.
}
void setup()
{
lcd.begin(16, 2);// set up the LCD's number of columns and rows:
lcd.clear();
Serial.begin(9600);
pinMode(READSOILPIN, INPUT); //Sensors pin (A1, A2),
pinMode(READSOILPIN2, INPUT);
pinMode(WATERPIN3, OUTPUT); // Dw(3, 2) to activate water pump
pinMode(WATERPIN2, OUTPUT);
}
void loop()
{
static int mode = MODE_RUN;
int lcd_key = read_LCD_buttons();
if (mode == MODE_RUN)
{
if (lcd_key == btnLEFT)
{
mode = MODE_CALIBRATE;
lcd.clear();
lcd.print("Calibrate 1");
}
else
{
run(lcd_key);
}
}
else if (mode == MODE_CALIBRATE)
{
if (calibrate(lcd_key) == true)
{
mode = MODE_RUN;
}
}
}/*
perform calibration
in:
button
returns:
true when calibration finished, else false
*/
bool calibrate(int btn)
{
if (btn == btnRIGHT)
{
// save value
lcd.clear();
lcd.print("done");
delay(500); // indicate calibration finished
lcd.clear();
return true;
}
if (btn == btnUP){
//for (int MAXDRY1=0; MAXDRY1 <= 1023; MAXDRY1++){ (tried this, didn't work)
lcd.clear();
lcd.print("mas");
lcd.print(MAXDRY1); // It keeps printing "0"
MAXDRY1 = MAXDRY1++;
} // do increment/decrement
//}
if (btn == btnDOWN)
{
lcd.clear();
lcd.print("menos");
lcd.print(MAXDRY1); // it only prints the value "0"
MAXDRY1 = MAXDRY1--;
}
// indicate calibration still in progress
return false;
}
void run(int btn) // This is the only part that works fine :s
{
if (btn == btnNONE){
float SensorValue1 = analogRead(READSOILPIN); //take a sample
float SensorValue2 = analogRead(READSOILPIN2); //take a sample
float hum1 = (1- (SensorValue1/1023))*100;
float hum2 = (1- (SensorValue2/1023))*100;
lcd.clear();
lcd.setCursor(0,0); // Sets the cursor to col 0 and row 0
lcd.print("Humedad:"); // Prints Sensor Val: to LCD
lcd.setCursor(0,1);
lcd.print(hum1); // Prints value on Potpin1 to LCD
lcd.print("%/"); // Prints Sensor Val: to LCD
lcd.print(hum2);
lcd.print("%");// Prints value on Potpin1 to LCD
if(SensorValue1 >= MAXDRY1)
{
// if the soil is too dry start watering for 3/4 a second then
// wait for 5 seconds before monitoring again
digitalWrite(WATERPIN3, HIGH);
delay(WATERDELAY);
digitalWrite(WATERPIN3, LOW);
delay(WATERPOSTDELAY);
}
if(SensorValue2 >= MAXDRY2)
{
// if the soil is too dry start watering for 3/4 a second then
// wait for 5 seconds before monitoring again
digitalWrite(WATERPIN2, HIGH);
delay(WATERDELAY);
digitalWrite(WATERPIN2, LOW);
delay(WATERPOSTDELAY);
}
}
}
Then calibrate mode works, but it adds more than 1 at a time, say if the value is 20, it adds 35 or 39 or 28. With the changes to lower case and maxdry1++.
With run (lcd_key) enabled I can access the calibration mode sometimes. If I press the left button after a while it works. Don't know why it only works sometimes.
// LcdKeypad - Version: Latest
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define MODE_RUN 0
#define MODE_CALIBRATE 1
#define WATERPIN3 3
#define WATERPIN2 2
#define READSOILPIN A1
#define READSOILPIN2 A2
// higher number is more dry
#define WATERDELAY 5000
#define WATERPOSTDELAY 5000
int maxdry1 = 700;
int maxdry2;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int read_LCD_buttons() // read the buttons
{
int adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
// We make this the 1st option for speed reasons since it will be the most likely result
if (adc_key_in > 1000) return btnNONE;
// For V1.0 comment the other threshold and use the one below:
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE; // when all others fail, return this.
}
void setup()
{
lcd.begin(16, 2);// set up the LCD's number of columns and rows:
lcd.clear();
Serial.begin(9600);
pinMode(READSOILPIN, INPUT);
pinMode(READSOILPIN2, INPUT);
pinMode(WATERPIN3, OUTPUT);
pinMode(WATERPIN2, OUTPUT);
}
void loop()
{
static int mode = MODE_RUN;
int lcd_key = read_LCD_buttons();
if (mode == MODE_RUN)
{
if (lcd_key == btnLEFT)
{
mode = MODE_CALIBRATE;
lcd.clear();
lcd.print("Calibrate 1");
lcd.print(maxdry1);
}
else
{
run(lcd_key);
}
}
else if (mode == MODE_CALIBRATE)
{
if (calibrate(lcd_key) == true)
{
mode = MODE_RUN;
}
}
}/*
perform calibration
in:
button
returns:
true when calibration finished, else false
*/
bool calibrate(int btn)
{
float SensorValue1 = analogRead(READSOILPIN); //take a sample
float SensorValue2 = analogRead(READSOILPIN2);
if (btn == btnRIGHT)
{
// save value
lcd.clear();
lcd.print("done");
delay(500); // indicate calibration finished
lcd.clear();
return true;
}
if (btn == btnUP){
//for (int maxdry1=0; maxdry1 <= 1023; maxdry1++){
lcd.clear();
lcd.print("mas ");
lcd.print(maxdry1);
maxdry1 = maxdry1 + 1;
lcd.setCursor(0,1);
lcd.print("(");lcd.print(SensorValue1);lcd.print(")");
} // do increment/decrement
//}
if (btn == btnDOWN)
{
lcd.clear();
lcd.print("menos");
lcd.print(maxdry1);
maxdry1 = maxdry1 - 1;
lcd.setCursor(0,1);
lcd.print("(");lcd.print(SensorValue1);lcd.print(")");
}
// indicate calibration still in progress
return false;
}
void run(int btn)
{
if (btn == btnNONE){
float SensorValue1 = analogRead(READSOILPIN); //take a sample
float SensorValue2 = analogRead(READSOILPIN2); //take a sample
float hum1 = (1- (SensorValue1/1023))*100;
float hum2 = (1- (SensorValue2/1023))*100;
lcd.clear();
lcd.setCursor(0,0); // Sets the cursor to col 0 and row 0
lcd.print("Humedad:"); // Prints Sensor Val: to LCD
lcd.setCursor(0,1);
lcd.print(hum1); // Prints value on Potpin1 to LCD
lcd.print("%/"); // Prints Sensor Val: to LCD
lcd.print(hum2);
lcd.print("%");// Prints value on Potpin1 to LCD
if(SensorValue1 >= maxdry1)
{
// if the soil is too dry start watering for 3/4 a second then
// wait for 5 seconds before monitoring again
digitalWrite(WATERPIN3, HIGH);
delay(WATERDELAY);
digitalWrite(WATERPIN3, LOW);
delay(WATERPOSTDELAY);
}
if(SensorValue2 >= maxdry2)
{
// if the soil is too dry start watering for 3/4 a second then
// wait for 5 seconds before monitoring again
digitalWrite(WATERPIN2, HIGH);
delay(WATERDELAY);
digitalWrite(WATERPIN2, LOW);
delay(WATERPOSTDELAY);
}
}
/*if (btn == btnLEFT){
int mode;
mode == MODE_CALIBRATE;
}*/
}
Then calibrate mode works, but it adds more than 1 at a time, say if the value is 20, it adds 35 or 39 or 28. With the changes to lower case and maxdry1++.
Sounds like a bouncing problem. Quick test is to add a delay(50) at the beginning of the calibration function.
If that fixes / improves the situation, you need to find a permanent solution; best is a millis() based solution (see the debounce example that comes with the IDE to get the idea) inthe function that reads the buttons.
I added the delay before the calibration process, but to get to the calibration mode from run mode, still takes a while to read the button. How can I make it change modes as soon as I press the button?.
// LcdKeypad - Version: Latest
#include <EEPROM.h>
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define MODE_RUN 0
#define MODE_CALIBRATE 1
#define WATERPIN3 3
#define WATERPIN2 2
#define READSOILPIN A1
#define READSOILPIN2 A2
// higher number is more dry
#define WATERDELAY 5000
#define WATERPOSTDELAY 5000
int maxdry1;
int maxdry2;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int read_LCD_buttons() // read the buttons
{
int adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
// We make this the 1st option for speed reasons since it will be the most likely result
if (adc_key_in > 1000) return btnNONE;
// For V1.0 comment the other threshold and use the one below:
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE; // when all others fail, return this.
}
void setup()
{
lcd.begin(16, 2);// set up the LCD's number of columns and rows:
lcd.clear();
Serial.begin(9600);
pinMode(READSOILPIN, INPUT);
pinMode(READSOILPIN2, INPUT);
pinMode(WATERPIN3, OUTPUT);
pinMode(WATERPIN2, OUTPUT);
EEPROM.read (1);
EEPROM.read (2);
}
void loop()
{
static int mode = MODE_RUN;
int lcd_key = read_LCD_buttons();
if (mode == MODE_RUN)
{
if (lcd_key == btnLEFT)
{
mode = MODE_CALIBRATE;
lcd.clear();
lcd.print("Calibrate 1");
lcd.print(maxdry1);
}
else
{
run(lcd_key);
}
}
else if (mode == MODE_CALIBRATE)
{
if (calibrate(lcd_key) == true)
{
mode = MODE_RUN;
}
}
}/*
perform calibration
in:
button
returns:
true when calibration finished, else false
*/
bool calibrate(int btn)
{
float SensorValue1 = analogRead(READSOILPIN); //take a sample
float SensorValue2 = analogRead(READSOILPIN2);
if (btn == btnRIGHT)
{
// save value
lcd.clear();
lcd.print("done");
delay(500); // indicate calibration finished
lcd.clear();
return true;
}
if (btn == btnUP){
//for (int maxdry1=0; maxdry1 <= 1023; maxdry1++){
lcd.clear();
lcd.print("mas ");
delay(50);
lcd.print(maxdry1);
maxdry1 = maxdry1 + 1;
lcd.setCursor(0,1);
lcd.print("(");lcd.print(SensorValue1);lcd.print(")");
} // do increment/decrement
//}
if (btn == btnDOWN)
{
lcd.clear();
lcd.print("menos");
delay(50);
lcd.print(maxdry1);
maxdry1 = maxdry1 - 1;
lcd.setCursor(0,1);
lcd.print("(");lcd.print(SensorValue1);lcd.print(")");
}
EEPROM.write (1,maxdry1);
EEPROM.write (2,maxdry2);
// indicate calibration still in progress
return false;
}
void run(int btn)
{
if (btn == btnSELECT){
float SensorValue1 = analogRead(READSOILPIN); //take a sample
float SensorValue2 = analogRead(READSOILPIN2); //take a sample
float hum1 = (1- (SensorValue1/1023))*100;
float hum2 = (1- (SensorValue2/1023))*100;
lcd.clear();
lcd.setCursor(0,0); // Sets the cursor to col 0 and row 0
lcd.print("Humedad:"); // Prints Sensor Val: to LCD
lcd.setCursor(0,1);
lcd.print(hum1); // Prints value on Potpin1 to LCD
lcd.print("%/"); // Prints Sensor Val: to LCD
lcd.print(hum2);
lcd.print("%");// Prints value on Potpin1 to LCD
maxdry1 = EEPROM.read(1);
maxdry2 = EEPROM.read(2);
if(SensorValue1 >= maxdry1)
{
// if the soil is too dry start watering for 3/4 a second then
// wait for 5 seconds before monitoring again
digitalWrite(WATERPIN3, HIGH);
delay(WATERDELAY);
digitalWrite(WATERPIN3, LOW);
delay(WATERPOSTDELAY);
}
if(SensorValue2 >= maxdry2)
{
// if the soil is too dry start watering for 3/4 a second then
// wait for 5 seconds before monitoring again
digitalWrite(WATERPIN2, HIGH);
delay(WATERDELAY);
digitalWrite(WATERPIN2, LOW);
delay(WATERPOSTDELAY);
}
}
/*if (btn == btnLEFT){
int mode;
mode == MODE_CALIBRATE;
}*/
}
The intention was one delay in the beginning for testing. But ok, did it fix the problem?
And you can't get direct responses on a button that bounces. You will have to wait till the button is stable (either pressed or released). 50ms should be barely noticeable.
The only long delay that you have is after writing the eeprom (by the looks of it), not sure why you have that.
The delays fixed it.
And the EEprom write is there to save the set value of maxdry, in case the arduino loses power.
It still takes about 1 minute before I can access the calibration mode. Don't know what else to change/add.