0

in an Arduino sketch a user is invited to input a number representing a time in the format HH:MM, this number is to be added at the end of an ordered and limited sequence of times

--the first input (lower limit) can be any time within the 24 hours,

--the upper limit is calculated as lower_limit+period; with period being 1,2,3,4,6,8,12 or 24 hours,

--and to be accepted, the input must verify that it is chronologically after the previous element, and that it's within the given period;

for example if first element is 20:00 and the period is 8, the upper limit will be 20+8=28 wich is 04:00; both 21:00 and 03:00 are accepted, where'is 19:00, 05:00, 09:00, 17:00, ... are rejected.

without any information on the 'day', i did not find any suitable algorithm, and none of the available Arduino libraries is useful in this case.

any link, or tip,...

closed as off-topic by Juraj, sempaiscuba, VE7JRO, SDsolar, MatsK Apr 28 '18 at 20:45

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question does not appear to be about Arduino, within the scope defined in the help center." – Juraj, sempaiscuba, VE7JRO, SDsolar, MatsK
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    Are the numbers inputted via Serial? On the first example, is it correct that any time from inclusive 20:01 to 04:00 will be accepted? – Maximilian Gerhardt Apr 28 '18 at 10:29
  • This smacks of homework to me.... – Majenko Apr 28 '18 at 10:44
  • Tip: work in minutes. The modulus (%) operator is your friend. – Majenko Apr 28 '18 at 10:44
  • @maximilian-gerhardt: numbers are inputted via buttons... any number from 20:01 to 04:00 are accepted if it's chronologically after the last element before the upper limit... – moyoumos Apr 28 '18 at 10:58
  • You have numerous problems here - how to enter the times, how to convert that entered time into minutes, how to compare those times properly. Tackle it one thing at a time. – Majenko Apr 28 '18 at 11:06
0

Here is the basic idea and a sample implementation for solving the problem:

The problem is: Given a start time time1 and a period period, each described by a pair of (hour,minute), how can we check whether another time time2 is within time1 to time1 + period?

First we can see that we given a (hour, minute) pair we can compute the total number of minutes as totalMinutes = 60*hour + minute.

Then we can observe that there two distinct cases that we must check:

  • the entire "time check period", that is, time1 to time1 + period is within 00:00 to 24:00 without overflowing past 24:00 when we simply add the times. then, we can use a simple bounds check worded as "time2 must be greater than time1 and less or equal to time1 + period when comparing total minnutes.
  • time1 + period overflows past 24:00. We consider an example of time1= 20:00 and period = 8:00. Thus all valid times are from 20:00 to 04:00 with an implicit "wrap around" at 24:00 to 00:00. We can see that there are now two time-intervals we must check: Everything from 20:01 to 24:00 and from 00:00 to 04:00 is valid. Thus we can derive the the bounds in minutes again. We can obtain the 04:00 by computing 20:00 + 08:00 modulo 24:00. The C operator % is used to compute the residue of the division by a certain number. I.e. 28 % 24 = 4 because 28 / 24 = 1 residue 4. This is called modulo-arithmetic.

The following C++ program demonstrates the solution:

#include <cstdio>

/* returns whether time2 defined by hour2:minute2 is within the period time1 = hour1:minute1 to time1 + period. */
bool is_time_within_period(
    int hour1, int minute1, 
    int hour2, int minute2,
    int periodHour, int periodMinute) {

        //Reject garbage input
        if(hour1 > 24 || hour2 > 24 
            || minute1 > 60 || minute2 > 60
            || periodHour > 24 || periodMinute > 60) {
                //TODO throw error message
                return false;
        }

        //Convert hours and minutes into absolute minutes. One hour is 60 minutes.
        int time1Minutes = 60 * hour1  + minute1;
        int periodMinutes = 60 * periodHour + periodMinute;
        int time2Minutes  = 60 * hour2 + minute2;

        int periodEnd = time1Minutes + periodMinutes;

        //If the start time plus the period time is over 24:00 there is a wrap-around the we need to consider.
        bool wrapAround = false;
        if( periodEnd > (24 * 60)) {
            wrapAround = true;
        }

        bool result = false;

        //printf("Wrap: %d Period end %d\n", wrapAround, periodEnd);

        if(!wrapAround) {
            //if there is no wrap-around we can just compare the total minutes against each other
            //time1 must be after time2 but before (time1 + period).
            result = time2Minutes <= (time1Minutes + periodMinutes) && time2Minutes > time1Minutes;
        } else {
            //There was a wrap around, i.e. start time + period was beyond 24:00.
            //We need to make two comparisons: is it in the time period from time1Minutes to 24:00?
            result = time1Minutes < time2Minutes && time2Minutes <= (24 * 60);

            //the result can also be okay if it from the time from 00:00 to the remaining period
            //use the module operator here. This transforms e.g. 28:00 would be reduced to 04:00. (modulo 24 hours calculated in minutes)
            int upper = (periodEnd % (24 * 60));
            //printf("Upper: %d (%02d:%02d)\n", upper, (upper / 60), upper % 60);
            result |= time2Minutes >= 0 && time2Minutes <= upper;
        }

        return result;
}

int main() {

    const int hourStart = 20;
    const int minuteStart = 0;

    const int periodHours = 8;
    const int periodMinutes = 0;

    //play around with these values
    const int compareTimeHour  = 4;
    const int compareTimeMinute = 0;

    printf("Start: %02d:%02d\n", hourStart, minuteStart);
    printf("Period: %02d:%02d\n", periodHours, periodMinutes);
    printf("Check time: %02d:%02d\n", compareTimeHour, compareTimeMinute);


    bool res = is_time_within_period(hourStart, minuteStart, compareTimeHour, compareTimeMinute, periodHours, periodMinutes);

    if(res) {
        printf("Time is within bounds\n");
    } else {
        printf("Time is not within bounds\n");
    }

    printf("Hello\n");

    return 0;
}

The function is_time_within_period has no dependencies and can thus be copy-pasted into any Arduino sketch.

Let the start time be 20:00 and the period 04:00. Then feeding the program different times to compare against lets us see that it indeed works.

Start: 20:00
Period: 08:00
Check time: 20:00
Time is not within bounds

Start: 20:00
Period: 08:00
Check time: 20:01
Time is within bounds

Start: 20:00
Period: 08:00
Check time: 04:00
Time is within bounds

Start: 20:00
Period: 08:00
Check time: 04:01
Time is not within bounds
  • it was very simple: if there is a wrap-around in the comparison interval; then we divide this interval in two at the point of this wrap-around... thanks and +5... – moyoumos Apr 28 '18 at 13:43
  • The function is_time_within_period has no dependencies and can thus be copy-pasted into any Arduino sketch. – moyoumos Apr 28 '18 at 13:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.