Using Button to change variable value on the go

Hello everyone,

I am working on a water level management device. Based on Atmega328 (but current prototype on atmega 1280), It monitors the level via ultrasonic sensor SRC-04. When the tank is almost full it shuts off the pump and when the tank is almost one third it switches it on. There is also a LM35 to monitor temp. Till this point every thing works fine. The problem is as under:

I would like to provide two buttons to set the upper and lower limit of water level when pump should switch on or off. I envisioned it to be two buttons to increase the value till it reaches 100% then starts at 0% again, for each upper and lower limit. I had planed to use ext interrupts for this but i think i was wrong and they are not meant to be used like this. Now i am not sure how to manage this issue.

Any inputs are welcome, thanks..

I expect that when the button is pressed, instead of deiplaying the current level and temp, the screen displays "Set High Level" and "Set lower level" with the other button. But the screen just flickrs and does nothing noticiable.

I am sure i am making a real dumb noobie mistake, please point it out and point me in the right direction.

The code is attahed below:

/*
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
*/ 
  
#include <LiquidCrystal.h>
#include <NewPing.h>

#define TRIGGER_PIN  8  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     9  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 500 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
#define RELAY_PIN    10  // Output pin for relay
#define TEMP_PIN     15  // Temp LM35 sensor input pin
#define STATUS_LED   13  // Status LED Blinking active
#define STATUS_MOTER 11  // Motor ON OFF LED

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
LiquidCrystal lcd(5, 6, 0, 1, 2, 3);

float temp;
float level;
float markLOW;
float  markHIGH;

void setup() {
  //Serial.begin(115200);       // used for debugging
  lcd.begin(16, 2);
  attachInterrupt(2, button1, RISING);
  attachInterrupt(3, button2, RISING);
  constrain(markLOW, 0, 105);
  constrain(markHIGH, 0, 105);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(TEMP_PIN, INPUT);
  pinMode(STATUS_LED, OUTPUT);
  pinMode(STATUS_MOTER, OUTPUT);
 }

void loop() {
   // Wait a while between pings (about 15 pings/min). 29ms should be the shortest delay between pings.
  digitalWrite(STATUS_LED, HIGH);
  delay(300);
  digitalWrite(STATUS_LED, LOW); 
  
  
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  temp = analogRead(TEMP_PIN);
  temp = temp * 0.48828125;
  level = uS / US_ROUNDTRIP_CM;
  level = map(level, 0, 130, 100, 0);
     
  lcd.setCursor(0, 0);
  lcd.print("Level:");
  lcd.print(level);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("Temperature:");
  lcd.print(temp);
  lcd.print("C");
  
   if ( level >= markHIGH)
 {
   digitalWrite(RELAY_PIN, LOW);
   digitalWrite(STATUS_MOTER, LOW);
 }
   else if ( level <= markLOW)
 {
   digitalWrite(RELAY_PIN, HIGH);
   digitalWrite(STATUS_MOTER, HIGH);
 } 
}

void button1() {
  delay(1000);
markLOW = markLOW + 5;
if (markLOW = 105)
{
  markLOW = 0;
}
  lcd.setCursor(0, 0);
  lcd.print("Set Low Level");
  lcd.setCursor(0, 1);
  lcd.print(markLOW);
  lcd.print("%");
  delay(5000);
}

void button2() {
  delay(1000);
markHIGH = markHIGH + 5;
if (markHIGH = 105)
{
  markHIGH = 0;
}
  lcd.setCursor(0, 0);
  lcd.print("Set High Level");
  lcd.setCursor(0, 1);
  lcd.print(markHIGH);
  lcd.print("%");
  delay(5000);
}

another method i tried was with "while" and later "if" function, but the program loops only at "Set Low Level".
Code attached

/*
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
*/ 
  
#include <LiquidCrystal.h>
#include <NewPing.h>

#define TRIGGER_PIN  8  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     9  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 500 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
#define RELAY_PIN    10  // Output pin for relay
#define TEMP_PIN     15  // Temp LM35 sensor input pin
#define STATUS_LED   13  // Status LED Blinking active
#define STATUS_MOTER 11  // Moter ON OFF LED
#define BUTTON1 	 21  // Button 1
#define BUTTON2 	 20  // Button 2

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
LiquidCrystal lcd(5, 6, 0, 1, 2, 3);

float temp;
float level;
float markLOW;
float  markHIGH;

void setup() {
  //Serial.begin(115200);
  lcd.begin(16, 2);
  constrain(markLOW, 0, 105);
  constrain(markHIGH, 0, 105);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(TEMP_PIN, INPUT);
  pinMode(STATUS_LED, OUTPUT);
  pinMode(STATUS_MOTER, OUTPUT);
 }

void loop() {

  // while the button1 is pressed, do the following
  while (digitalRead(BUTTON1) == HIGH) {
    button1();
	delay(2000);
  }
  
  // while the button1 is pressed, do the following
  while (digitalRead(BUTTON2) == HIGH) {
    button2();
	delay(2000);
  }

   // Wait a while between pings (about 15 pings/min). 29ms should be the shortest delay between pings.
  digitalWrite(STATUS_LED, HIGH);
  delay(300);
  digitalWrite(STATUS_LED, LOW); 
  
  
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  temp = analogRead(TEMP_PIN);
  temp = temp * 0.48828125;
  level = uS / US_ROUNDTRIP_CM;
  level = map(level, 0, 130, 100, 0);
     
  lcd.setCursor(0, 0);
  lcd.print("Level:");
  lcd.print(level);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("Temperature:");
  lcd.print(temp);
  lcd.print("C");
  
   if ( level >= markHIGH)
 {
   digitalWrite(RELAY_PIN, LOW);
   digitalWrite(STATUS_MOTER, LOW);
 }
   else if ( level <= markLOW)
 {
   digitalWrite(RELAY_PIN, HIGH);
   digitalWrite(STATUS_MOTER, HIGH);
 } 
  //Serial.print("markLOW");
  //Serial.println(markLOW);
  //Serial.print("markHIGH");
  //Serial.println(markHIGH);
}

void button1() {
  
markLOW = markLOW + 5;

if (markLOW = 105){
  markLOW = 0;
}
  lcd.setCursor(0, 0);
  lcd.print("Set Low Level");
  lcd.setCursor(0, 1);
  lcd.print(markLOW);
  lcd.print("%");
  delay(500);
}

void button2() {

markHIGH = markHIGH + 5;

if (markHIGH = 105){
  markHIGH = 0;
}
  lcd.setCursor(0, 0);
  lcd.print("Set High Level");
  lcd.setCursor(0, 1);
  lcd.print(markHIGH);
  lcd.print("%");
  delay(500);
}

I am not really experienced with coding, but i m here to learn, thanks for all your help. :slight_smile:

Rahul

You can draw a flowchart and study it using the best tool : your understanding of every decision and loop and time.

Thanks,

I have tried making sense of it all but to no avail.

I believe that it is due to some basic issue of coding as i am new to coding and must be doing something wrong. Hope someone can point it out.

Thanks

Reading your code, in setup() you use constrain() but with no sense.

How you write and use the constrain(), seem to me that you aspect the program automatically have 2 limit for the variable.

constrain() is a function like max()
You must read the return value:

markLOW=constrain(markLOW, 0, 105);

and use this istruction everywhere you read markLOW from, example, an analogpin.

Thanks,

Yes thats what I intended to do. Made the necessary changes.

Any idea how to manage the main issue?

Thanks again

if (markLOW = 105)

Nope. Assignment vs Equality.

There are a couple of issues with how the interrupt code is written, but the second version of the code looks good. I suspect a wiring issue. The fact that it's looping on the Button1() code points to the digitalRead(BUTTON1) returning HIGH. Are you using pull-down resistors and wiring the buttons to 5V?

So you feel the second code seems theoretically correct?

I will check the wiring once again and run this again and see if that helps. No i was not employing a pullup/down resistor (now i realize i should, so making the changes). Earlier it was 5v ----> resistor ----> tactical push button -----> input pin

Will update once i check this..

Thanks

rhl.thakur:
I will check the wiring once again and run this again and see if that helps. No i was not employing a pullup/down resistor (now i realize i should, so making the changes). Earlier it was 5v ----> resistor ----> tactical push button -----> input pin

Which isn't right. Simplify it: Use INPUT_PULLUP instead of INPUT, and connect one of the switches leads to the input pin, and the other to GND.

I would use the internal pull-up, and connect to the ground. But if you do that, you have to change the code to activate on LOW instead of HIGH.

Yes that seems like a better way to do it :stuck_out_tongue:

will do use in the internal pullup.

thanks guyes :smiley: