-
touble with a time calculation
Hi guys , having a mind block on a time calculation
what i need is to set a time and show the amount of time that has occurred past (OVERTIME ) that set time
the hours mins , sec is working ok as a count up clock
the calculation fails when overtime goes to 1min is sec 0 etc
eg if the set value is say 0 hours , 0 mins 10sec
the overtime clock will start counting past 10sec
Code:
OT_Hours = Hours - set_hour
OT_Minutes = Minutes - set_Min
OT_Seconds = Seconds -set_sec
-
Re: touble with a time calculation
OT_Hours = 0 OT_Minutes = 0 OT_Seconds = 0
#stop clock here for the test otherwise sec/min rollovers during if tests will give incorrect results
if Hours > set_hour then OT_Hours = Hours - set_hour
if Minutes > set_Min then OT_Minutes = Minutes - set_Min
if Seconds > set_sec then OT_Seconds = Seconds -set_sec
#resume clock
note hour rollover to next day is not taken into account
-
Re: touble with a time calculation
hi richard , the main clock cant be stopped and needs to be a running test
the rollover from sec to mins is the issue as well as mins to hours
with the Set_Day= 0, Set_Hour= 0 ,Set_min= 0, Set_sec = 10
this code has that issue of when the clock roles over
the OT variables are used to display the OT clock
Days, Hours, Mins,Secs variables are the main clock
"Set_" varables are the time allowed
the OT clock is only enabled after the Set time is = > than the main clock
Code:
if OT_Days => Set_Day and OT_Hours => Set_Hour and OT_Minutes => Set_Min and OT_Seconds => Set_OT_Sec then OT_Enable = 1
if OT_Enable = 1 THEN
if Days > Set_Day then OT_Days = Days - Set_Day
if Hours > Set_Hour then OT_Hours = Hours - Set_Hour
if Minutes > Set_Min then OT_Minutes = Minutes - Set_Min
if Seconds > Set_Sec then OT_Seconds = Seconds - Set_Sec
endif
-
Re: touble with a time calculation
corrected code to be, so only OT is enabled and shown when Set time matched or exceeded , but roll over is still the problem
Code:
if Days => Set_Day and Hours => Set_Hour and Minutes => Set_Min and Seconds => Set_OT_Sec then OT_Enable = 1
if OT_Enable = 1 THEN
OT_Days = Days - Set_Day
OT_Hours = Hours - Set_Hour
OT_Minutes = Minutes - Set_Min
OT_Seconds = Seconds - Set_Sec
endif
-
Re: touble with a time calculation
I have the same sort of problems comparing multibyte values that increment in isr routines , the only solutions I can find are to
1. stop the clock then compare vars (disable interrupts)
2. compare the vars in the "clock" isr where they wont change as you compare them
3. maybe have a special case for seconds=59, minutes=59 and seconds=59 , seconds= 59 and minutes=59 and hour=23 (if seconds and minutes and hours are all single byte vars )
option 3 seems flaky
-
Re: touble with a time calculation
Why not try something straight forward as this?
Code:
' run this every second along with your clock code
if (Hours >= Set_Hours AND Minutes >= Set_Min AND Seconds >= Set_Sec)
OT_Seconds = OT_Seconds+1
if (OT_Seconds > 59)
OT_Seconds = 0
OT_Minutes = OT_Minutes+1
if (OT_Minutes > 59)
OT_Minutes = 0
OT_Hours = OT_Hours+1
' you may want to restrict / rollover the hours to 24 hours format here.
endif
endif
endif
-
Re: touble with a time calculation
I have a main clock in place
the overtime clock = main clock - set time
the problem occures when the clock value roles over and the clockvalue - set_time < 0
during that time the value of the OT clock is incorrect
eg set time = 10 sec , when main clock counts to 1min , the over time clock would show 0.50 instead of 0.51 etc, for the duration of main clock moving 1.00 - 1.10 , then it be fine
this approch seems to be correct but i am not sure if it needs to be nested
Code:
if Days => Set_Day and Hours => Set_Hour and _
Minutes => Set_Min and Seconds => Set_Sec and _
100th => Set_100th then OT_Enable = 1
if OT_Enable = 1 THEN
OT_Days = Days - Set_Day
OT_Hours = Hours - Set_Hour
OT_Minutes = Minutes - Set_Min
OT_Seconds =Seconds - Set_sec
OT_100th = 100TH - Set_100th
endif
if Hours - Set_Hour <0 then
OT_Days = Days - 1
OT_Hours = 24 - Set_Day + Hours
endif
if Minutes - Set_Min <0 then
OT_Hours = OT_Hours - 1
OT_Minutes = 60 - Set_Min + Minutes
endif
if Seconds - Set_Sec <0 then
OT_Minutes = OT_Minutes - 1
OT_Seconds = 60 - Set_Sec + Seconds
endif
if 100TH - Set_100th <0 then
OT_Seconds = OT_Seconds - 1
Ot_100TH = 100 - Set_100th + 100TH
endif
-
Re: touble with a time calculation
Code:
if Hours - Set_Hour <0 then
OT_Days = Days - 1
OT_Hours = 24 - Set_Hour + Hours
endif
typo fixed
-
Re: touble with a time calculation
hows this going to work
if Days => Set_Day and Hours => Set_Hour and _
Minutes => Set_Min and Seconds => Set_Sec and _
100th => Set_100th then OT_Enable = 1
imagine set day=0 set hour=1 set min=30
if hour = 2 and min=29 then it will test false when it should be true
u need to think in terms of timestamp
timestamp= sec+min*60 +hour*3600 etc day * whatever. (unix does it from some arcane date in 1980 in microseconds)
then compare timestamp
this will not solve rollovers however
from wiki
unix timestamp 00:00:00 UTC on January 1, 1970
-
Re: touble with a time calculation
just for the sake of an argument on a raspberry pi
you could just go datetime.datetime(now)-settime and you wold get a RESULT in years,months,days,hours,minutes,seconds and microseconds
a pi costs about 40 bucks has 512m of ram usb and Ethernet built in . makes life easy
-
Re: touble with a time calculation
A clock does not have values of
24 hours
60 min
60 sec
100 100th
for example a clock showing 59 seconds will change to 0 on the next second.
the calculation
if Seconds - Set_Sec <0 then
OT_Minutes = OT_Minutes - 1
OT_Seconds = 60 - Set_Sec + Seconds
endif
should be
if Seconds - Set_Sec <0 then
OT_Minutes = OT_Minutes - 1
OT_Seconds = 59 - Set_Sec + Seconds
endif
and the same for the other < comparisons.
-
Re: touble with a time calculation
Quote:
Originally Posted by
richard
just for the sake of an argument on a raspberry pi
you could just go datetime.datetime(now)-settime and you wold get a RESULT in years,months,days,hours,minutes,seconds and microseconds
a pi costs about 40 bucks has 512m of ram usb and Ethernet built in . makes life easy
Are you advising us all to use Raspbbery Pi?
-
Re: touble with a time calculation
not at all however it depends on the size of the task ,think of moving bricks with a Toyota corolla if you only need to move a few its fine, to move 10000 would be an ordeal better suited to a tray truck with hydraulic loader.
pbp is a great product but if you want to do a lot with floats, longs , singed math , datetime objects colour gui's etc then other platforms and languages make life a lot easier.
-
Re: touble with a time calculation
Easy does not increase understanding.
Unfortunately we live in a plug and play world. The Pi was created to address the issue of children not understanding how computers work and introduce them to programming so it is made easy to produce quick results and grab their imagination. What it does not do is teach electronics. But as I have never had one my opinion is not a first hand informed one.
Anyway this thread is about time calculation not Pi and have we just hijacked a thread which is against the rules?
-
Re: touble with a time calculation
do I understand the problem correctly
I'm assuming we have a set time day-h:m:s.xx ie day 0 hour 2 minute 30 sec 28.34 and that we then subsequently read a clock and calculate the elapsed time between now and the set time if and only if the now time is greater than the set time .
is this right ?
-
Re: touble with a time calculation
Richard No.
longpole001's program counts down to set time then counts up after set time.
-
Re: touble with a time calculation
in fact i have several clock timers running for this project , most are based on the master timer with other value settings to change the displayed results
for this task the time counter counts up from 0 , the set _time value is the length of time before trigging the overtime clock , which counts up to show the total amount of time exceeding the set_time values
when the main timer exceeds the set_time then a secondary timer ( overtime clock ) is enabled and then shows and continues to run until the main timer stops
as seen if the overtime clock values = main clock - set time , when a sec , min , hour roles over , a < 0 value will occur untill the time value = set_time value again
-
Re: touble with a time calculation
Quote:
Originally Posted by
longpole001
as seen if the overtime clock values = main clock - set time , when a sec , min , hour roles over , a < 0 value will occur untill the time value = set_time value again
Yes that is exactly what your code does. I did wonder if that was what you wanted to do.
I was also thinking if this is necessary
if Days => Set_Day and Hours => Set_Hour and _
Minutes => Set_Min and Seconds => Set_Sec and _
100th => Set_100th then OT_Enable = 1
and what would be the implications of just having this
OT_Days = Days - Set_Day
OT_Hours = Hours - Set_Hour
OT_Minutes = Minutes - Set_Min
OT_Seconds =Seconds - Set_sec
OT_100th = 100TH - Set_100th
if Hours - Set_Hour <0 then
OT_Days = Days - 1
OT_Hours = 23 - Set_Day + Hours
endif
if Minutes - Set_Min <0 then
OT_Hours = OT_Hours - 1
OT_Minutes = 59 - Set_Min + Minutes
endif
if Seconds - Set_Sec <0 then
OT_Minutes = OT_Minutes - 1
OT_Seconds = 59 - Set_Sec + Seconds
endif
if 100TH - Set_100th <0 then
OT_Seconds = OT_Seconds - 1
Ot_100TH = 99 - Set_100th + 100TH
endif
Just a thought :)
-
Re: touble with a time calculation
the reason for the enable is that until the time = > the setting , the output is not displayed , also the enable flag is used for other routines , hardware options and other timers., also if the values of the Set time all are 0 then that disables the flag for this timer for display on the Glcd's and other outputs
there are several timer clock options that need to show - time in secs only , mins+ sec only , hours,min, sec only ,currently these options turn off / on flags inside the main up/ down timer counter code to enable hours, mins ,sec changes
by changing the values to 59 from 60 for say the secs this results in the following
if set_hour= 0 set_min = 0, Set_sec = 10
if main elapsed time now shows = 0 hour, 1 min , 0 sec
If OT_sec = 60 - Set_sec + Seconds(main elapsed ) then
OT display = 50 (60 - 10 + 0)
if OT_sec = 59 - Set_sec + Seconds(main elapsed ) then
OT display = 49 (59 - 10 + 0)
if the event time was set for 10 sec and the main time is now 1 min then the overtime should read 50secs , not 49 sec
I think i have this correct , but i am still testing
cheers
Sheldon
-
Re: touble with a time calculation
if you have a clock running
try this
h m s var bytes (current time )
x y z var byte (old time )
a b c var byte ( time difference)
carry var bit
time_difference: (assumes current time > old time)
carry=0
c=s-z
if c>127 then
c=c+60
carry=1
endif
b=m-(y+carry)
if b>127 then
b=b+60
carry=1
else
carry=0
endif
a=h-(x+carry)
if a>127 then
a=a+24
carry=1 ;extra day needed to be added
else
carry=0
endif
return
-
Re: touble with a time calculation
that should work as well richard , cheers
the mind block orginally came from not sure why i was seeing the output i was , and finding that the <0 resulted in the displayed variables being incorrect during that time
-
Re: touble with a time calculation
well after a few more tests that did not work well , yes , when you enter a event period of 10sec for the event time or 1 min or 1 hour , 1day then code answers earlier will allow for the <0 error when it roles over , but its does not when you combine Event set time for say 1 m 10 sec
so lets start again
sounds simple but its giving me a problem
GOAL
------
the count up elapsed base timer is counting up from 0 , when the set time values are => then time set for the event the Overtime clock is enabled starts counting up to show the time past the set time
code references
---------------
Base Elapsed timer is set to count up = EL1
Overtime Clock = EL2
Event1_OT_xxx = Time set duration for event
EL1 has the standard time duration if statements enabled so that sec = 60 then sec = 0 , min = min +1 , same for hour , day 0 then 1 min , etc etc for counting up
Code:
'------- Event overrun timer 1--------
if EL1_Days => Event1_OT_Day and EL1_hOURS => Event1_OT_Hour and _
EL1_Minutes => Event1_OT_Min and EL1_Seconds => Event1_OT_Sec and _
EL1_100th => Event1_OT_100th then EL2_Enable = 1
if Event1_OT_Day = 0 and Event1_OT_hour = 0 and Event1_OT_Min = 0 and _ ' if all values are 0 , then dont enable the overrun timer
Event1_OT_sec = 0 and Event1_OT_100th = 0 then EL2_Enable = 0
if EL2_Enable = 1 THEN ; EL2 = EL1 current values - set overrun value
EL2_Days = EL1_Days - Event1_OT_Day
EL2_Hours = EL1_Hours - Event1_OT_hour
EL2_Minutes = EL1_Minutes - Event1_OT_Min
EL2_Seconds = EL1_Seconds - Event1_OT_sec
EL2_100th = EL1_100TH - Event1_OT_100th
endif
addings code to allow for <0 error ( EL1_Seconds - Event1_OT_sec) - this occurs when secs role over 1min but the work arround is not working when combined with sat set times of 1min 10 sec
any further sugestions
-
Re: touble with a time calculation
its never going to work if you don't allow for the negative carry (borrow) , subtracting time is no different to subtracting base (16 12 10 8 2 ) numbers except that hours are base 24 , minutes and seconds are base 60 . have a look again at my example note the order of calculation also
-
Re: touble with a time calculation
i'll say it again if the el1 time data vars update in real time via an isr (as I suspect they may) the whole process is flawed unless you can fix (stop the clock) the el1 time vars for the duration of the subtraction .
-
Re: touble with a time calculation
i thought about just starting another clock by using the base ticks but i cant cos
EL0 is the master clock elasped clock , which counts up or down and when started is not stoped untill reset
EL1 is copy of EL0 - used to display the time and has enable /disable to stop the count on EL1 on display , then enable EL1 copies the current values from the master clock to EL1
EL2 is the overtime clock based on the values of EL1 - set event times
this why i really need to correct the errors in EL2 values by using EL1 - set times as far as i can see
-
Re: touble with a time calculation
hi richard yes sent you a pm on this
cheers
Sheldon
-
Re: touble with a time calculation
Code:
if EL2_Enable = 1 THEN ; EL2 = EL1 current values - set overrun value
EL2_100th = EL1_100TH - Event1_OT_100th+100
if EL2_100th<100 then
EL1_Seconds=EL1_Seconds-1
Else
EL2_100th=EL2_100th-100
endif
EL2_Seconds = EL1_Seconds - Event1_OT_sec+60
if EL2_Seconds<60 then
EL1_Minutes=EL1_Minutes-1
else
EL2_Seconds =EL2_Seconds -60
endif
EL2_Minutes = EL1_Minutes - Event1_OT_Min +60
if EL2_Minutes<60 then
EL1_Hours=EL1_Hours-1
else
EL2_Minutes =EL2_Minutes -60
endif
EL2_Hours = EL1_Hours - Event1_OT_hour+24
if EL2_Hours<24 then
EL1_Days=EL1_Days-1
else
EL2_Hours =EL2_Hours -24
endif
EL2_Days = EL1_Days - Event1_OT_Day
endif
Just something to try
-
Re: touble with a time calculation
steve has the right idea for the math but since el1/el2 vars can be updated via the isr at any time during the calcs the results will vary.
statisticly it will fail about 4-5 times per hundred calcs based on :-
I think chances of failure are 1/60+1/60+1/100+1/24 I might be wrong about the stats
-
Re: touble with a time calculation
If isr affects EL1 vars create Temp_EL1 vars at the start of the routine and use these for the calculation.
-
Re: touble with a time calculation
won't work . the isr can change the values as u copy them to the temp vars ,been there done that
-
Re: touble with a time calculation
Ok some problems do not have an answer.
Bye
-
Re: touble with a time calculation
only solution I know is to disable isr and copy vars to a buffer then enable isr and then perform calcs on the buffered data.
it may mean the odd lost interrupt / whats worse incorrect calcs or missed ints
only the designer can make that call .
-
Re: touble with a time calculation
the isr updates EL0,EL1 , EL2 during the call
the isr reloads timer1 every 10ms , then updates EL0-2 variables during that call and displaying them take time ,
a long as the running display is clearly correct for EL2 =EL1 - set_times for sec,min, hour ,day , then i think it be ok.
at the moment its just show the totaly wrong values for duration of the set time
-
Re: touble with a time calculation
thanks guys
ill try both ways i rather not have wrong calculations but i also know this interupt is serviced every 10ms , and the E0-2 varables should be correct for that amount of time ??
-
Re: touble with a time calculation
that's the wrong way to think about it , you can never know when the 10ms period will start or finish , this way is better.
the interrupt latency with a 32mHZ clk will be about 10uS anyway , time to copy 4 bytes to a buffer say 4 uS , the interrupt will only be deferred 4uS plus another couple for the int disable enable worst case you'll hardly notice
-
Re: touble with a time calculation
hI GUYS , using the code by steve seems to work , a small change cos i use EL1 values to show the current time value , so any changes that change the EL1 values in the calculating the EL2 , is not possible so i need to copy the values of EL1 to EL3 , then use EL3 as a temp group
I am trying to disable the interupt whilest in the ISR subroutine , before the copy of EL0 to EL1-3 , then re -enable interrupt after ,
but i get a interrupt priority state not found error when compile atm
-
Re: touble with a time calculation
it serves no purpose to stop the isr from within the isr , its a waste of time copying the el vars to a buffered copy inside the isr .
time in your case is in essence a multi byte var , the value is volatile and cannot be guaranteed outside the isr when the isr is running.
the correct procedure is
disable isr
copy bytes to buffer
enable isr
do your subtraction
-
Re: touble with a time calculation
-
Re: touble with a time calculation
steve was wodering what the code may be if i was to use the el1 values plus event1 setting to the overrun point , and use say event 2 seting to show the amount time left before overrun , eg EL0 is counting up , copied to EL1 for display , Event 1 setts time for the overrun , Event2 sets time to show time before reching the overrun time , EL3 displays the time counting down to reach time set by Event1 time.
-
Re: touble with a time calculation
Probably easy to do. Post some code from the relevant section for me to look at.