A discussion group for the PICMicro microcontroller. Also called the Microchip PIC, this list is dedicated to the use and abuse of this fine, simple, microcontroller. Close to topic posts are welcome, ie. general electronics.
PICs and multiple operations - Paul - Apr 13 4:25:47 2009
Hello.
Has anyone any experience with PICs and doing muliple things at once? Here is a example of
what i mean
Sensor 1 On -> Timer 1 -> Output 1 On -> Timer 2 -> Output 2 Off
Sensor 2 On -> Timer 3 -> Output 2 On -> Timer 4 -> Output 2 Off
Both the sequences need running at once. I have done a project that can run this, but i'm
sure there are many ways to acheive this.
My method was to give each sequence a data bank, and increment this bank for every stage
of the sequence
E.g (not correct code)
If SeqA=0 call Check Sensor 1 On
If SeqA=1 call Timer 1
If SeqA=2 call Timer 2
If SeqB=0 call Check Sensor 2 On
If SeqB=1 call Timer 3
If SeqB=2 call Timer 4
Back to top
Check Sensor 1 On
Is sensor 1 on?
No Return
Yes- SeqA= SeqA+1 + Continue
Timer 1
Is timer value done?
No Return
Yes - SeqA = SeqA+1 + Continue
etc..
Hope this makes a bit of sence! Basically, if was doing one sequence, i could loop on the
btfss for ever untill the bit changed, as with the timer, but i need do multiple
operations, i need to jump about a bit. But the way i have a done it, seems very long
winded! I also worry that if my timer has a low scaler in the config, i could miss that
important match!
Cheers all
Paul
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: PICs and multiple operations - Phil Seakins - Apr 13 4:54:35 2009
You need to set up a "state machine". It's just a simple endless loop with
sections which check for inputs and assign states and section which assign
outputs and timers etc depending on state. A "state" is just a variable with
different, usually incrementing values, each of which represents a different
"state". Eg 0 = idle, 1 = set timer 1, 2 = waiting timer 1, 3 = output 1 set
and timer 2 waiting, etc.
On 4/13/09, Paul
wrote:
>
> Hello.
> Has anyone any experience with PICs and doing muliple things at once? Here
> is a example of what i mean
>
> Sensor 1 On -> Timer 1 -> Output 1 On -> Timer 2 -> Output 2 Off
> Sensor 2 On -> Timer 3 -> Output 2 On -> Timer 4 -> Output 2 Off
>
> Both the sequences need running at once. I have done a project that can run
> this, but i'm sure there are many ways to acheive this.
>
> My method was to give each sequence a data bank, and increment this bank
> for every stage of the sequence
>
> E.g (not correct code)
>
> If SeqA=0 call Check Sensor 1 On
> If SeqA=1 call Timer 1
> If SeqA=2 call Timer 2
>
> If SeqB=0 call Check Sensor 2 On
> If SeqB=1 call Timer 3
> If SeqB=2 call Timer 4
>
> Back to top
>
> Check Sensor 1 On
> Is sensor 1 on?
> No Return
> Yes- SeqA= SeqA+1 + Continue
>
> Timer 1
> Is timer value done?
> No Return
> Yes - SeqA = SeqA+1 + Continue
>
> etc..
>
> Hope this makes a bit of sence! Basically, if was doing one sequence, i
> could loop on the btfss for ever untill the bit changed, as with the timer,
> but i need do multiple operations, i need to jump about a bit. But the way i
> have a done it, seems very long winded! I also worry that if my timer has a
> low scaler in the config, i could miss that important match!
>
> Cheers all
> Paul
>
______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )Re: PICs and multiple operations - Wouter van Ooijen - Apr 13 5:32:08 2009
Paul wrote:
>
> Hello.
> Has anyone any experience with PICs and doing muliple things at once?
> Here is a example of what i mean
>
> Sensor 1 On -> Timer 1 -> Output 1 On -> Timer 2 -> Output 2 Off
> Sensor 2 On -> Timer 3 -> Output 2 On -> Timer 4 -> Output 2 Off
>
> Both the sequences need running at once. I have done a project that can
> run this, but i'm sure there are many ways to acheive this.
>
> My method was to give each sequence a data bank, and increment this bank
> for every stage of the sequence
Nothing wrong with your approach, but you could just make a main loop
that calls the 'handling' or each 'task', like:
main:
call handle_sensor_1
call handle_sensor_2
goto main
Each 'handling' must of course have its private variables, and must be
aware in what state it is (stored in one of those variables).
A variation is to have the main loop check whether there is an event
that warrants the calling of each handler, and do so only when such an
even has occurred, but personally I prefer to let the 'handler' sort
that out.
Note that a handler can not 'wait': that would lock up all other
handlers. My favorite way to handle delays is to have a small delay at
the top of the main loop, so a handler can wait by counting until it has
been called a sufficient number of times.
If your timing needs to be so accurate that the processing time of the
handlers influences the timing too much, you can replace the delay with
more intelligent code that awaits a timer rollover, so the timing
becomes independent of the processing time.
As for missing an event: calculate how often your handlers must be
called, and arrange your loop so that this requirement is satisfied. If
not, you have a problem, and the handlers must be re-coded to take less
time. (defer some processing to the next call).
This is my favorite architecture for a real-time program. In nearly all
cases I had at hand, interrupts were not needed.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: PICs and multiple operations - Dennis Clark - Apr 13 15:19:34 2009
Hello back,
The nature of the beast is that you can't do two things at the same
time. However, you can look like you are very simply. Use a state
machine. This is how most of us that do embedded work handle multiple
activities. At its core a state machine is simply a perpetual loop,
each time through the loop you do the next activity that is usually
determined by the last thing (state) handled in the loop.
I like to have a background timer run in an interrupt that I can use to
handle a system timer or clock. Every time that I need to refer to a
time I record the current value of the system clock as a local variable.
When enough time has elapsed, I increment the state to move to the next
thing to do. You can have states that themselves implement other state
machines as well.
Each of your "phases" below can be a state within that sequences state
machine. Each of these functions can be run from a loop running at the
highest level.
You're on the right track. State machines implemented with "switch"
constructs using local static state variables can handle these tasks
elegantly in an easy to understand way. At least that is how I typically
do it.
DLC
> Hello.
> Has anyone any experience with PICs and doing muliple things at once? Here
> is a example of what i mean
>
> Sensor 1 On -> Timer 1 -> Output 1 On -> Timer 2 -> Output 2 Off
> Sensor 2 On -> Timer 3 -> Output 2 On -> Timer 4 -> Output 2 Off
>
> Both the sequences need running at once. I have done a project that can
> run this, but i'm sure there are many ways to acheive this.
>
> My method was to give each sequence a data bank, and increment this bank
> for every stage of the sequence
>
> E.g (not correct code)
>
> If SeqA=0 call Check Sensor 1 On
> If SeqA=1 call Timer 1
> If SeqA=2 call Timer 2
>
> If SeqB=0 call Check Sensor 2 On
> If SeqB=1 call Timer 3
> If SeqB=2 call Timer 4
>
> Back to top
>
> Check Sensor 1 On
> Is sensor 1 on?
> No Return
> Yes- SeqA= SeqA+1 + Continue
>
> Timer 1
> Is timer value done?
> No Return
> Yes - SeqA = SeqA+1 + Continue
>
> etc..
>
> Hope this makes a bit of sence! Basically, if was doing one sequence, i
> could loop on the btfss for ever untill the bit changed, as with the
> timer, but i need do multiple operations, i need to jump about a bit. But
> the way i have a done it, seems very long winded! I also worry that if my
> timer has a low scaler in the config, i could miss that important match!
>
> Cheers all
> Paul
> ------------------------------------
>
> to unsubscribe, go to http://www.yahoogroups.com and follow the
> instructions
______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.
(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: PICs and multiple operations - "John J. McDonough, WB8RCR" - Apr 13 16:49:55 2009
----- Original Message -----
From: "Paul"
To:
Sent: Monday, April 13, 2009 4:25 AM
Subject: [piclist] PICs and multiple operations
> Hello.
> Has anyone any experience with PICs and doing muliple things at once? Here
> is a example of what i mean
Don't be afraid of using interrupts. In a lot of cases, interrupts can
greatly simplify your code. But the advice to look at a state machine is
good. That is the standard way to keep track of multiple things, but
depending on your app, it can sometimes get a little involved when you have
multiple things to juggle.
Interrupts can be especially handy, and easy, in dealing with the timers.
Again, depending on your PIC and your app, the PIC timers tend to be pretty
quick, so you end up using the timer expiration to increment a counter so
you can count long periods of time. This is a particularly handy thing to
do inside the timer interrupt, especially since it allows your timing to be
pretty accurate while still being pretty leisurely inside your main state
machine (although if "Output On" is simply setting a pin high, you aren't
going to be challenged for time!).
Also, don't be afraid to run the PIC clock slow, maybe very slow. This will
not only extend the time of the hardware timers, but will reduce your power
consumption. If you don't need to be accurate to the microsecond, why not
simplify your code and reduce power consumption by running the PIC at kHz
instead of MHz. 32 kHz crystals or resonators are cheap and widely
available, and if your timing requirements are loose, you can have any clock
you want on the cheap with an RC clock.
--McD
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )Re: PICs and multiple operations - Wouter van Ooijen - Apr 14 1:31:59 2009
> Don't be afraid of using interrupts. In a lot of cases, interrupts can
> greatly simplify your code.
I disagree. Do be afraid of using interrupts, try to do without if at
all possible. Interrupts can make your application much more complex,
especially to test.
Note that I don't say that interrupts don't have their place, but IMHO
they should be sued only as a last resort.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions
______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.
(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: PICs and multiple operations - dlc - Apr 14 2:19:54 2009
I tend to agree with Wouter. I use an interrupt for running my
background timer clock. Pretty much everything else is polled in a
state machine with timing done using that background clock. However,
this assumes that all my other IO is either not timing critical or that
I have dedicated hardware handling those things that are (like UARTs,
CAN, RF, etc.) that allow buffering.
I only use interrupts for unpredictable events that are timing critical.
DLC
Wouter van Ooijen wrote:
>> Don't be afraid of using interrupts. In a lot of cases, interrupts can
>> greatly simplify your code.
>
> I disagree. Do be afraid of using interrupts, try to do without if at
> all possible. Interrupts can make your application much more complex,
> especially to test.
>
> Note that I don't say that interrupts don't have their place, but IMHO
> they should be sued only as a last resort.
>
--
Question with boldness even the existence of a God;
because, if there be one, he must more approve of the
homage of reason, than that of blind-folded fear.
Thomas Jefferson
-------------------------------------------------
Dennis Clark TTT Enterprises
www.techtoystoday.com
-------------------------------------------------
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: PICs and multiple operations - Wouter van Ooijen - Apr 14 2:36:35 2009
> I only use interrupts for unpredictable events that are timing critical.
I definitely agree that one should use interrupts when one must. The
debate (if there is one) is whether to sue interrupts when other
solutions (in most cases: state machines polled by a main loop) are
possible.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions
______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.
(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: PICs and multiple operations - Paul Laverick - Apr 16 17:20:10 2009
Thanks for all the replies everyone, its great to get all your ideas flowing!
Paul
From: Paul
Sent: Monday, April 13, 2009 9:25 AM
To: p...@yahoogroups.com
Subject: [piclist] PICs and multiple operations
Hello.
Has anyone any experience with PICs and doing muliple things at once? Here is a example of
what i mean
Sensor 1 On -> Timer 1 -> Output 1 On -> Timer 2 -> Output 2 Off
Sensor 2 On -> Timer 3 -> Output 2 On -> Timer 4 -> Output 2 Off
Both the sequences need running at once. I have done a project that can run this, but i'm
sure there are many ways to acheive this.
My method was to give each sequence a data bank, and increment this bank for every stage
of the sequence
E.g (not correct code)
If SeqA=0 call Check Sensor 1 On
If SeqA=1 call Timer 1
If SeqA=2 call Timer 2
If SeqB=0 call Check Sensor 2 On
If SeqB=1 call Timer 3
If SeqB=2 call Timer 4
Back to top
Check Sensor 1 On
Is sensor 1 on?
No Return
Yes- SeqA= SeqA+1 + Continue
Timer 1
Is timer value done?
No Return
Yes - SeqA = SeqA+1 + Continue
etc..
Hope this makes a bit of sence! Basically, if was doing one sequence, i could loop on the
btfss for ever untill the bit changed, as with the timer, but i need do multiple
operations, i need to jump about a bit. But the way i have a done it, seems very long
winded! I also worry that if my timer has a low scaler in the config, i could miss that
important match!
Cheers all
Paul

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: PICs and multiple operations - Paul Laverick - Apr 19 13:09:38 2009
Thanks for all the replies everyone, its great to get all your ideas flowing!
Paul
From: Paul
Sent: Monday, April 13, 2009 9:25 AM
To: p...@yahoogroups.com
Subject: [piclist] PICs and multiple operations
Hello.
Has anyone any experience with PICs and doing muliple things at once? Here is a example of
what i mean
Sensor 1 On -> Timer 1 -> Output 1 On -> Timer 2 -> Output 2 Off
Sensor 2 On -> Timer 3 -> Output 2 On -> Timer 4 -> Output 2 Off
Both the sequences need running at once. I have done a project that can run this, but i'm
sure there are many ways to acheive this.
My method was to give each sequence a data bank, and increment this bank for every stage
of the sequence
E.g (not correct code)
If SeqA=0 call Check Sensor 1 On
If SeqA=1 call Timer 1
If SeqA=2 call Timer 2
If SeqB=0 call Check Sensor 2 On
If SeqB=1 call Timer 3
If SeqB=2 call Timer 4
Back to top
Check Sensor 1 On
Is sensor 1 on?
No Return
Yes- SeqA= SeqA+1 + Continue
Timer 1
Is timer value done?
No Return
Yes - SeqA = SeqA+1 + Continue
etc..
Hope this makes a bit of sence! Basically, if was doing one sequence, i could loop on the
btfss for ever untill the bit changed, as with the timer, but i need do multiple
operations, i need to jump about a bit. But the way i have a done it, seems very long
winded! I also worry that if my timer has a low scaler in the config, i could miss that
important match!
Cheers all
Paul
______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.
(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: PICs and multiple operations - aditya pathak - May 1 18:13:21 2009
Hi,
you wanted to do multiple thing at once, the best you can
achive it by RTOS , even in PIC's MCU you can do that by using C
lanuage and using Pumpkin Rtos. Even some example you can find on
pumpkin.com... plz visit & try it ..
Yours,
Adu.......
On 4/13/09, Paul
wrote:
> Hello.
> Has anyone any experience with PICs and doing muliple things at once? Here
> is a example of what i mean
>
> Sensor 1 On -> Timer 1 -> Output 1 On -> Timer 2 -> Output 2 Off
> Sensor 2 On -> Timer 3 -> Output 2 On -> Timer 4 -> Output 2 Off
>
> Both the sequences need running at once. I have done a project that can run
> this, but i'm sure there are many ways to acheive this.
>
> My method was to give each sequence a data bank, and increment this bank for
> every stage of the sequence
>
> E.g (not correct code)
>
> If SeqA=0 call Check Sensor 1 On
> If SeqA=1 call Timer 1
> If SeqA=2 call Timer 2
>
> If SeqB=0 call Check Sensor 2 On
> If SeqB=1 call Timer 3
> If SeqB=2 call Timer 4
>
> Back to top
>
> Check Sensor 1 On
> Is sensor 1 on?
> No Return
> Yes- SeqA= SeqA+1 + Continue
>
> Timer 1
> Is timer value done?
> No Return
> Yes - SeqA = SeqA+1 + Continue
>
> etc..
>
> Hope this makes a bit of sence! Basically, if was doing one sequence, i
> could loop on the btfss for ever untill the bit changed, as with the timer,
> but i need do multiple operations, i need to jump about a bit. But the way i
> have a done it, seems very long winded! I also worry that if my timer has a
> low scaler in the config, i could miss that important match!
>
> Cheers all
> Paul
>
--
Yours,
Aditya Pathak
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )Re: PICs and multiple operations - Dwayne Reid - May 1 22:14:17 2009
At 02:25 AM 4/13/2009, Paul wrote:
>Hello.
>Has anyone any experience with PICs and doing muliple things at
>once? Here is a example of what i mean
>
>Sensor 1 On -> Timer 1 -> Output 1 On -> Timer 2 -> Output 2 Off
>Sensor 2 On -> Timer 3 -> Output 2 On -> Timer 4 -> Output 2 Off
Wouter's suggestion of using state machines is a good one - that's
exactly how I would approach this.
Most of the stuff I do runs slowly, so keep that in mind while I
describe my approach. What I mean by slowly is everything appears to
be instantaneous to a human (millisecond reaction times) but is slow
compared to how quickly a modern computer might operate.
My main loop has a number of state machines, each located after the
previous one. Each state machine is a task or part of a task. The
end of the main loop calls my timing subroutine - this waits for a
timer tick (1ms in my case), then performs all of the housekeeping
routines. Upon return from the timer tick subroutine, the main loop
jumps back to the top of the loop and services all of the state machines again.
Housekeeping routines:
watchdog stuff
A/D conversions
timer ticks (10ms, 100ms, 250ms, 1 sec, 20 seconds, 1 minute, 60 minutes)
serial i/o (deals with TX & RX buffers)
slow SPI stuff (1 clock edge per 1ms tick)
fast but short SPI stuff (1 byte per 1ms tick)
lots of other stuff I can't think of right now.
The idea is that I have a framework where all of the housekeeping
stuff that is common to many (most?) projects is handled in the background.
The foreground (all of those state machines) contains the code that
is specific to the particular project.
Each state machine (SM) has 1 or more bytes of RAM associated with
it. At least 1 byte of RAM is needed for each state machine to keep
track of which state that SM is currently in. The front of each
state machine contains a short jump table with enough entries for all
of the states. Upon entering any particular SM, the RAM byte that
contains the current state for that SM is added to the program
counter so that the PIC jumps to the right place in that SM.
Couple of minor refinements: Most of the state machines I use have
less than 16 states. So: I use only the lower nibble to contain the
current state. The upper nibble can contain flag bits or, most often
for me, a loop counter that can count from 0 through 15. The
advantage of using the upper nibble for a loop counter is that you
increment the counter by adding 0x10 to the RAM byte (doesn't affect
the state number in the lower nibble) and the "C" flag becomes set
when the counter rolls over from 0xFn to 0x0n - makes it easy to check.
I *always* mask the RAM byte that is used to compute the jumps so
that a completely wacky value doesn't jump way past the end of the
jump table. I also always make the jump table long enough to handle
the highest possible state number - unused states at the end of the
table just cause the SM to reset back to state 0.
Every state machine exits immediately if it waiting for something to
happen (external input, timer tick, etc). That allows subsequent SMs
to continue operating.
States that might take a very long time (more than 100us or so are
broken down into smaller tasks if possible. For example, one project
has a 48 bit divide routine within it. If I recall, it takes
something like 2500 clock cycles to execute. The number that is
being calculated is not time-critical, so the divide routine is
broken into much smaller (shorter) time slices. Only part of the
calculation is done at any one time and it takes multiple timer ticks
for the calculation to finish. That's not a problem in that project.
I can dig up some examples if the above is not clear.
Finally, Wouter suggests avoiding interrupts if possible. That's
good advice. Pretty much the only place I use interrupts is for
handling time-critical stuff such as serial i/o communications -
emptying the RX register when a byte is received, putting a new byte
into the TX register when the current byte has been sent. These
interrupt routines are generally short and fast.
Hope this helps.
dwayne
--
Dwayne Reid
Trinity Electronics Systems Ltd Edmonton, AB, CANADA
(780) 489-3199 voice (780) 487-6397 fax
www.trinity-electronics.com
Custom Electronics Design and Manufacturing
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )