Hello, I hope I may ask this question, bcs I have a brainhandicap, sometimes
I cannot find or interpret things.
I must make a timer, that can be switched to different timecounting.
One is 16 hours in one go, the other is something like 30 seconds per day.
And another time, I am not ready sure of.
I think I must use the "WAIT xx" - command on the 12F675
But I must be able to stop one of the timings and select the other,
by pressing a knob.
So I think I need an interrupt, otherwise the knobs will never be seen.
I thought of using GP3, GP4, GP5 for the interrupt. (1 spare for another timing)
As one of them is pressed, it must be recognised, and the program should jump
to a subroutine.
Can someone help me with that ?
Or, maybe someone has another Idea to stop the timing when a knob is pressed,
and jump to the subroutine belonged to the knob.
Kind regards,
Eddy
Last edit: Eddylvi 2018-03-29
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Not sure you need interrupts. Why not simpply loop thru checking the state of the inputs and use a timer to do the wait.
....resetofcodesetuptimerforthewaitofxxsecsormsecsdoforeveriftimerhasexpiredthenexitloopendififportsofthebuttons<>notpressedthen'therefore the not presssed equals zero saveportstate exit loop endif loop if test port state for which button was pressed do stuff end if .... reset of code
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
first: the idea with the stopwatch has only sideways to do with this timing.
I was just thinking of a way how to check a timing.
I am very sorry, that I do not completely understand your way of timing.
One of the timings is 16 hours in one go.
But I must be able to stop that by pressing the button for the other timing
that starts at the moment op pressing.
So, after, say, 6 hours, I press the other button, the program goes to the
other timingroutine and waits 23 hours and 59 minutes, switch the
batterycharger on, wait 1 minute, switch off, and start counting for the other
23h59 again, and stay in that loop until I press the other button for another
loop of 16 hours.
After starting the 16 hours, the output stays active for 16 hours, and after that
it goes on with the buffering of 23:59 waiting and switch on for 1 minute.
(Maybe it will be shortend to only 30 seconds)
The chargers I am using for this cost only some 7 euros, and can charge 8x AA or
8x AAA, and officially they only will be used for buffering a lot of NimH batteries.
But, if you have enough time it will be a shame, not being able to use the chargers
for normal charging.
That is why I wanted to have different timings.
If I come so far, I might count the chargingtime of the 16 hours and write that into
the EPROM, so that after powerfailure the charger will not start at the beginning,
after charging for 15 hours (making a total time of 31 hrs)
Kind regards,
Eddy
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Write the solution down in psudeo code. Do not worry about the language syntax. So, design the solution. Use words to describe what you are trying to achieve. As I did.
~~~~
.... rest of code
setup timer for 16 hours
set 24hours = true
do forever
do forever
if timer has expired then
exit loop
end if
if portsofthebuttons <> not pressed then 'therefore the not presssed equals zero
saveportstate... this may be more than one port
exit loop
endif
loop
if test port state equal no button pressed
'therefore after 16 hours
if 24hours = true
set output active
set timer for 16 hours
set 16hours = true
set 24hours = false
else
set output not active
set timer for 24 hours
set 16hours = false
set 24hours = true
I'm not sure how accurate you want these timings, but the internal oscillator is ( at best) only good to 1% so after 1 day could be up to 15 minutes slow or fast. With a clock crystal the timing should be (at worst) off by 10 ppm (1 second per day).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I found something strange: As long as the WAIT xx takes,
the WHOLE PROGRAM stand stil !
How can you give a listing that should work during the WAIT ?
That cannot be working than ?
I also found something else: WAIT UNTIL
Maybe I can get further with that.
Kind regards,
Eddy
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well, sorry if it hurts you, but the only thing I know for timing is WAIT.
That is why I started with great cow basic.
That is also why I came to the interrupts to stop a timing with WAIT.
Not everyone is a professional experienced softwaredesigner.
Sorry again when hurting, but I don't understand how I should make
a timing in another way, plus I hardly understand some English.
The only languages I understand are German and dutch.
And than even better German than dutch.
Kind regards,
Eddy
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Start will learning how to make a timer work. There are lots of demos with respect to this subject - look in the ..\GCB@SYN\GreatCowBasic\Demos\Interrupt_and_Timer_Solutions\Interrupt - Timed examples folder of your installation. You may have to use some variables to make the timer count for 24 and 16 hours (lots of seconds) but the first task for you is to sort setting a timer and detecting when the timer has expired (technically called overflowed).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Eddy,
A low accuracy solution would be a combination of wait and a counter.
"Wait" is a a slow pendulum and the counters are variables (sec and min).
This creates a low accuracy real time clock. I have used this is data loggers and on PLC machine controls and it works great.
How do you know that your "clock" / program is running? I like to include a led that flashes now and then, in this case once a sec.
To choose a mode I would uses a mode variable and then a case statement to branch to the right time. maybe 3 more leds to tell the operator what mode am i in? or single blinking led that quickly blinks the number of the mode and then long pause, like car error codes
main:Dowait1s' adjust to fine tune for better accuracy RTC 'incrementsthetimecounters' Check mode switches'blinkLEDloopSubRTCSec=Sec+1ifSec>59ThenSec=0scan=1Min=Min+1endififMin>59ThenMin=0scan=2Hour=Hour+1IfHour>30thenHour=1endifendsub
my 2 cents!
Good luck!
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My idea was after switching on the system, the program checks witch
mode it is in. (out of the eprom, just a simpel number)
(important for powerfailure)
If it is 'halfway' the 16h-mode it counts further until the end of the 16h.
To keep it easy, every 5 mins the counter in the eprom gets updated.
After the 16h, the system goes on into the buffermode.
In the buffermode the charger is switched off for 23:59' and after that
it is switched on for 1' and after that it starts again counting 23:59'.
By pressing a button one can chose to start normal charging with 16h,
after that also automatically into buffermode.
The easiest way for me was to use the wait-command, that is the only
reason I started using GCB.
And there is also an interrupt for changing inputpins.
So, if such an interrupt comes it wil then jump to the routine for the
chosen mode through one of the buttons.
But I am afraid I cannot get that working.
It is to difficult for me, and I can frow away my computers i special boght.
Because I do not use windos other than for gcb.
kind regards,
Eddy
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
To keep it easy, every 5 mins the counter in the eprom gets updated.
How long do you need this program to last?
EEPROM in the PIC16f877a is rated for 100,000 Erase/Write cycles.
Writing every 5 Min gives you 500,000 Min. = 11 Months, 12 Days, 5 hours and 20 min before your EEPROM fails give or take a week or so.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@Eddy. Do you look at the demos? Wait will just confuse you even more. Psuedo code for you.
Consider the code. Setup an interrupt and wait for 16hours. When the button is pressed the wait routine is interrupted. The handler is call. When the handler is done you will go back to the wait routine!
So, reconsider the approach.
....resetofcodeuponabuttonpresscallcodetohandlebuttonwait16hours....resetofcodesubhandlebuttonsiftestportstateforwhichbuttonwaspresseddostuffendif'at the end of this - the code should go back to the calling routine... else the stack will break, and lots of bad stuff will happen. 'donotbeusingGOTOtofixthis.endsub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@eddy - I cannot have you suffering. Here is your homework.
This sets up the timer, counts for a time slot - if it timeouts it setNoEventInTimerPeriod = true, you can test the buttons and do stuff.
And, look no wait.
It works - as I have written and tested it.
Anobium
#chip 16f877a, 4
#define buttonispressed porta.1
dir buttonispressed IN
#define LedOut porta.0
dir Ledout Out
dim HoursToCount as Byte
dim SecondsCounter,MaxSecondsInTheTimePeriod as long
dim NoEventInTimerPeriod as byte
'Init the Timer0
'Set the timer to 1ms
InitTimer0 Osc, PS1_1/4
On Interrupt Timer0Overflow call CountTime
Settimer 0, 6
Starttimer 0
MaxSecondsInTheTimePeriod = 1000 * 60 * 60 * HoursToCount SecondsCounter = 0 NoEventInTimerPeriod = false 'init to 16hours HoursToCount = 16 LedOut = !LedOut do forever if NoEventInTimerPeriod = true Then 'toggle the hours to count if HoursToCount = 16 Then HoursToCount = 24 else HoursToCount = 16 end if '1ms * 1000 = 1 sec. then, * 60 for one minute, then, * 60 for one hour, then * HoursToCount for the time period. MaxSecondsInTheTimePeriod = 1000 * 60 * 60 * HoursToCount
NoEventInTimerPeriod = false
end if
'check lots of buttons
'when buttons stuff happens change the time....do lots of stuff
if buttonispressed = 1 then
if HoursToCount = 16 Then
HoursToCount = 24
else
HoursToCount = 16
end if
'1ms * 1000 = 1 sec. then, * 60 for one minute, then, * 60 for one hour, then * HoursToCount for the time period.
MaxSecondsInTheTimePeriod = 1000 * 60 * 60 * HoursToCount
end if
loop
sub CountTime
SecondsCounter = SecondsCounter + 1
if SecondsCounter = MaxSecondsInTheTimePeriod then
'we have timed out... nothing happened in the time period
LedOut = !LedOut
NoEventInTimerPeriod = true
SecondsCounter = 0
end if
Settimer 0, 6
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If after the interrupt I say "go to the other routin" it still goes back where it come from ?
Hmmm...
I'll stop with everything, I don't understand anyway.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
many thanks for the code !!! I will try it, I hope I come further with it.
Tell me how I can reach you, I would like to send you a reward for the help !
As soon as I got it working ofcourse :-)
This problem is not the only one I have. So I am very, very frustrated.
But that is a loooooong looooong story.
Kind regards,
Eddy
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello, I hope I may ask this question, bcs I have a brainhandicap, sometimes
I cannot find or interpret things.
I must make a timer, that can be switched to different timecounting.
One is 16 hours in one go, the other is something like 30 seconds per day.
And another time, I am not ready sure of.
I think I must use the "WAIT xx" - command on the 12F675
But I must be able to stop one of the timings and select the other,
by pressing a knob.
So I think I need an interrupt, otherwise the knobs will never be seen.
I thought of using GP3, GP4, GP5 for the interrupt. (1 spare for another timing)
As one of them is pressed, it must be recognised, and the program should jump
to a subroutine.
Can someone help me with that ?
Or, maybe someone has another Idea to stop the timing when a knob is pressed,
and jump to the subroutine belonged to the knob.
Kind regards,
Eddy
Last edit: Eddylvi 2018-03-29
Hi Eddy.
Does this question relate to https://sourceforge.net/p/gcbasic/discussion/579125/thread/0d93866a/#9210 ?
Not sure you need interrupts. Why not simpply loop thru checking the state of the inputs and use a timer to do the wait.
Hello Anobium,
first: the idea with the stopwatch has only sideways to do with this timing.
I was just thinking of a way how to check a timing.
I am very sorry, that I do not completely understand your way of timing.
One of the timings is 16 hours in one go.
But I must be able to stop that by pressing the button for the other timing
that starts at the moment op pressing.
So, after, say, 6 hours, I press the other button, the program goes to the
other timingroutine and waits 23 hours and 59 minutes, switch the
batterycharger on, wait 1 minute, switch off, and start counting for the other
23h59 again, and stay in that loop until I press the other button for another
loop of 16 hours.
After starting the 16 hours, the output stays active for 16 hours, and after that
it goes on with the buffering of 23:59 waiting and switch on for 1 minute.
(Maybe it will be shortend to only 30 seconds)
The chargers I am using for this cost only some 7 euros, and can charge 8x AA or
8x AAA, and officially they only will be used for buffering a lot of NimH batteries.
But, if you have enough time it will be a shame, not being able to use the chargers
for normal charging.
That is why I wanted to have different timings.
If I come so far, I might count the chargingtime of the 16 hours and write that into
the EPROM, so that after powerfailure the charger will not start at the beginning,
after charging for 15 hours (making a total time of 31 hrs)
Kind regards,
Eddy
Write the solution down in psudeo code. Do not worry about the language syntax. So, design the solution. Use words to describe what you are trying to achieve. As I did.
~~~~
.... rest of code
setup timer for 16 hours
set 24hours = true
do forever
do forever
if timer has expired then
exit loop
end if
if portsofthebuttons <> not pressed then 'therefore the not presssed equals zero
saveportstate... this may be more than one port
exit loop
endif
loop
if test port state equal no button pressed
'therefore after 16 hours
if 24hours = true
set output active
set timer for 16 hours
set 16hours = true
set 24hours = false
else
set output not active
set timer for 24 hours
set 16hours = false
set 24hours = true
loop
.... rest of code
The same code, shown ablove, with some lines drawn on it!
Last edit: Anobium 2018-03-29
I'm not sure how accurate you want these timings, but the internal oscillator is ( at best) only good to 1% so after 1 day could be up to 15 minutes slow or fast. With a clock crystal the timing should be (at worst) off by 10 ppm (1 second per day).
Well, a few procent difference is not a big problem, special if it is in the
buffering mode. ( 1 minute / day )
I'll study the ideas.
Many many thanks !
Eddy
Hello again,
I found something strange: As long as the WAIT xx takes,
the WHOLE PROGRAM stand stil !
How can you give a listing that should work during the WAIT ?
That cannot be working than ?
I also found something else: WAIT UNTIL
Maybe I can get further with that.
Kind regards,
Eddy
@Eddy. We have had discussions in the past...... we recommend an approach as your online experts.
So, where in my advice did I say use WAIT?
Read what I recommended. If it rubbish then do ignore but you are going down the wrong route using WAIT.
Well, sorry if it hurts you, but the only thing I know for timing is WAIT.
That is why I started with great cow basic.
That is also why I came to the interrupts to stop a timing with WAIT.
Not everyone is a professional experienced softwaredesigner.
Sorry again when hurting, but I don't understand how I should make
a timing in another way, plus I hardly understand some English.
The only languages I understand are German and dutch.
And than even better German than dutch.
Kind regards,
Eddy
Start will learning how to make a timer work. There are lots of demos with respect to this subject - look in the ..\GCB@SYN\GreatCowBasic\Demos\Interrupt_and_Timer_Solutions\Interrupt - Timed examples folder of your installation. You may have to use some variables to make the timer count for 24 and 16 hours (lots of seconds) but the first task for you is to sort setting a timer and detecting when the timer has expired (technically called overflowed).
Eddy,
A low accuracy solution would be a combination of wait and a counter.
"Wait" is a a slow pendulum and the counters are variables (sec and min).
This creates a low accuracy real time clock. I have used this is data loggers and on PLC machine controls and it works great.
How do you know that your "clock" / program is running? I like to include a led that flashes now and then, in this case once a sec.
To choose a mode I would uses a mode variable and then a case statement to branch to the right time. maybe 3 more leds to tell the operator what mode am i in? or single blinking led that quickly blinks the number of the mode and then long pause, like car error codes
my 2 cents!
Good luck!
Mike
Both: Many thanks for the info.
My idea was after switching on the system, the program checks witch
mode it is in. (out of the eprom, just a simpel number)
(important for powerfailure)
If it is 'halfway' the 16h-mode it counts further until the end of the 16h.
To keep it easy, every 5 mins the counter in the eprom gets updated.
After the 16h, the system goes on into the buffermode.
In the buffermode the charger is switched off for 23:59' and after that
it is switched on for 1' and after that it starts again counting 23:59'.
By pressing a button one can chose to start normal charging with 16h,
after that also automatically into buffermode.
The easiest way for me was to use the wait-command, that is the only
reason I started using GCB.
And there is also an interrupt for changing inputpins.
So, if such an interrupt comes it wil then jump to the routine for the
chosen mode through one of the buttons.
But I am afraid I cannot get that working.
It is to difficult for me, and I can frow away my computers i special boght.
Because I do not use windos other than for gcb.
kind regards,
Eddy
How long do you need this program to last?
EEPROM in the PIC16f877a is rated for 100,000 Erase/Write cycles.
Writing every 5 Min gives you 500,000 Min. = 11 Months, 12 Days, 5 hours and 20 min before your EEPROM fails give or take a week or so.
@Eddy. Do you look at the demos? Wait will just confuse you even more. Psuedo code for you.
Consider the code. Setup an interrupt and wait for 16hours. When the button is pressed the wait routine is interrupted. The handler is call. When the handler is done you will go back to the wait routine!
So, reconsider the approach.
@eddy - I cannot have you suffering. Here is your homework.
This sets up the timer, counts for a time slot - if it timeouts it set
NoEventInTimerPeriod = true
, you can test the buttons and do stuff.And, look no wait.
It works - as I have written and tested it.
Anobium
If after the interrupt I say "go to the other routin" it still goes back where it come from ?
Hmmm...
I'll stop with everything, I don't understand anyway.
Look at the code - I posted. A working solution for you. See https://sourceforge.net/p/gcbasic/discussion/579126/thread/7dfc45b8/#b28a
Dear Anobium,
many thanks for the code !!! I will try it, I hope I come further with it.
Tell me how I can reach you, I would like to send you a reward for the help !
As soon as I got it working ofcourse :-)
This problem is not the only one I have. So I am very, very frustrated.
But that is a loooooong looooong story.
Kind regards,
Eddy
Make a donation to the certifcation for this software. That will reward everyone.
Good luck.