Problem about timer to on and off relay every 2 hours and 30 mins and secs

This is user input. I got a problem when combining it the hours, minutes and secs.

#include <Keypad.h>

int relay_pin = A2;

long int timer = 0;

const int ROW_NUM = 4; //four rows
const int COLUMN_NUM = 3; //three columns

char keys[ROW_NUM][COLUMN_NUM] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte pin_rows[ROW_NUM] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = {5, 4, 3}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );


String input_value;

void setup() {

  pinMode(relay_pin, OUTPUT);


  Serial.begin(9600);
  input_value.reserve(32); // maximum input characters is 33, change if needed
}

void loop() {
  char key = keypad.getKey();

  if (key) {
    Serial.print("Time: ");
    Serial.println(key);
    
    
    if (key == '*') {
      input_value = ""; // clear input value
    } else if (key == '#') {

      timer = input_value.toInt();


     timer = timer * 1000; //time in seconds
      //timer = timer * 1000 * 60; //time in minuts
     // timer = timer * 1000 * 60 * 60; //time in hours
      do{
      delay(timer);
      digitalWrite(relay_pin, HIGH);
      Serial.println("relay on");

      delay(5000);
      digitalWrite(relay_pin, LOW);
      Serial.println("relay off");
      }while(timer != 0);

      timer = 0;



      input_value = ""; // clear input value
    } else {
      input_value += key; // append new character to input value string
    }
  }
}

Tell us a bit more.


BTW
Do not use delay( ) or do( ) as they will result in a blocking code situation.

Once you enter the above loop you will NEVER exit it!

You should specify

what is the final purpose of your project?

pressing a keypad switching a relay is not a self-purpose

What kind of visual feedback is given to the user that the user is able to see that pressing a key on the keypad is really recognised by the device?

how many keypresses shall the user do?
What shall these keypressed represent?

one digit hour two digits minutes two digits seconds?

example : 23059
which means
2 hours
30 minutes
59 seconds

After entering the time. Shall the device be locked to strictly execute keep relay switched on for the given time ignoring any keypressed until the given time is over?
or
shall the device be able to react on keypad-presses at any time to switch off the relay on user-input?

best regards Stefan

Well you seem to like to play a game of many many rounds of posting a short posting
invoking a new round of asking back for additional details.

my answer: "calculate SecondsOfDay with this calculation

SecondsOfDay = hours * 3600 + minutes * 60 + seconds.

This results in a number that increases 1 by 1 each second.
And comparing how much time has passed by is reduced to

if (SecondsOfDay > mySwitchOnTime)  {
  takeAction();
}

Of course this answer is not satifying. I have written this answer to set you into the position
of having too less information to make it work.

Where I'm in the position of having too less information from you to understand what you really want to do. The momentary poor information would force me to make a lot of assumptions writing down multiple suggestions. This is work I will not do.

You want help so it is you who has to provide a detailed description what you want.

One way to give such a description is
to just write down what a person that is just watching a user using your keypad can see:

user presses "C" on the keypad then .....
user presses .... on the keypad then ....

best regards Stefan

I tried that already in this code but it doesn't work. It just works in seconds but when I put a value in minutes or hours it doesn't work.

#include <millisDelay.h>

int setupHours = 0;    
int setupMinutes = 0;   
int setupSeconds = 0;  

millisDelay outHighDelay;
const unsigned long relayDelay = 4000;

millisDelay outLowDelay;
const unsigned long timer = setupSeconds * 1000 + (60 * setupMinutes * 1000) + (3600 * setupHours * 1000) ;

const int outPin = 12;

void setup() {
  pinMode(12, OUTPUT);
  digitalWrite(outPin, HIGH);
  outHighDelay.start(relayDelay);
}

void loop() {
  if (outHighDelay.justFinished()) {
    digitalWrite(outPin, LOW);
    outLowDelay.start(timer);
  }
  if (outLowDelay.justFinished()) {
    digitalWrite(outPin, HIGH);
    outHighDelay.start(relay);
  }
}

Try

const unsigned long timer = setupSeconds + (60 * setupMinutes) + (3600L * setupHours) ;

timer *= 1000L;

You may have been overflowing in your expression calculation.

Serial print out some values and see if they are correct, plausible.

setuoSeconds and the others could be unsigned int or unsigned long type.

a7

new idea it might be that the compiler has done 16bit calculations (on 8bit or 16bit microcontrollers.

the appendix "ul" to numbers tells the compiler use unsigned 32bit calculations. (ul as short for unsigned long

const unsigned long All_InSeconds = setupHours * 3600ul + setupMinutes * 60ul + setupSeconds;
const unsigned long All_InMilliSeconds = AllInSeconds * 1000ul;

and like mentioned above. If your code has a strange behaviour.
Print out serial debug output

best regards Stefan

Thanks it works now.

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