cooperative m*ultitasking + Precise timing

Discussion in 'Embedded Systems and Microcontrollers' started by Eric007, Sep 7, 2012.

  1. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33
    Hey!

    First I wanted to know how to create precise timing with PIC using internal osc.?

    I remember with AVR at school, we were loadind a value of *6* in the timer register so it could count from 6 to 255 or from 0 to 249! Can we apply that with PICs or there are better methods!

    But I now wondering if even this method *above* would really work...

    Another thing is writing a code where the *independent actions* of routines A, B, C,...depend on the pressing of a unique button (different) ...so I just wanted to confirm that it is possible to have a *key* routine (at top) that scans up to 8 buttons (given a register has 8 bits) and computes flags in a register for the routines A,B,C...I actually writing a code for that...

    *Oh my system is really dead can't think straight right now..

    heu how one would handle...assuming action of routine *A* is processed every X [ms] and *action* of routine *B*, every Y [ms]....

    where X is a multiple of Y, for instance

    A executes every 0.5 seconds and B executes every 1 second!

    I have a little idea but I was thinking maybe someone here have done it already and that can save me lots of time!

    Thanks!:)


    Code ( (Unknown Language)):
    1.  
    2.  
    3. main
    4.  
    5. call keyz
    6. call A
    7. call B
    8. call C
    9. call D
    10. ...
    11.  
    12. goto main
    13.  
     
  2. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33
    I think in the 1 second routine (in the above example) ima put action of the *0.5 second* routine too! Boom problem fixed! Now I would have to check the deadline of processing time...
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    First, the internal oscillator isn't very accurate so you can't.

    If "good enough" s acceptable then look for a PIC with a Timer2 module, which has a count & compare register. You can set that for exact counts.
     
  4. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    You can also use the CCP or MCCP module along with Timer 1 in "special event" mode which resets Timer 1 automatically for very precise intervals.

    As for multiple switch debounce and management, you've already seen examples of this from Joey and me. While there are several methods to choose from, I use one that relies on a switch state latch and simple parallel logic in order to filter out the unwanted switch states. That is, the routine flags a "new press" state for your main program while ignoring a "still pressed" state, a "new release" state, or a "still released" state. For example, sample switches in your ISR at 16 msec "debounce" intervals and simply test and clear the "new press" flag bits in the "flags" variable in your main program.

    Just a reminder... If you're unable or unwilling to learn how to use the MPLAB Simulator and Watch Window, you're really working at a disadvantage.

    Cheerful regards, Mike

    Code ( (Unknown Language)):
    1.  
    2. ;
    3. ;  swnew  ____---____-----_____   sample active lo switches
    4. ;  swold  _____---____-----____   switch state latch
    5. ;  swnew  ____-__-___-____-____   changes, press or release
    6. ;  swnew  ____-______-_________   filter out 'release' bits
    7. ;  flags  _____-------_________   toggle flag bits for main
    8. ;
    9. buttons
    10.         comf    PORTA,W         ; sample active lo switches       |B0
    11.         xorwf   swold,W         ; changes, press or release       |B0
    12.         xorwf   swold,F         ; update switch state latch       |B0
    13.         andwf   swold,W         ; filter out 'release' bits       |B0
    14.         xorwf   flags,F         ; toggle flag bits for main       |B0
    15.  
     
    Eric007 likes this.
  5. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    You can setup an interrupt that occurs at exactly 1mS. In the interrupt you inc some variables.

    Lets say you need to do an ADC task every 200mS, you make a variable called mS_ADC. That is incremented in the interrupt, every mS.

    Then to control your ADC task in your main code you do something ike this;
    Code ( (Unknown Language)):
    1.  
    2. main_loop
    3. {
    4.   if(mS_ADC >= 200)
    5.   {
    6.     mS_ADC -= 200;   // reset the timer variable
    7.     // then do the ADC task here
    8.   }
    9. }
    10.  
    You can have a number of tasks in the main loop, they will all work indepndently.

    If you want some more complex examples of some multitasking systems there is some info here;
    http://www.romanblack.com/PICthread.htm
     
  6. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33
    Ok thank!

    Oh yes! You can say that again...I use your code and his when it comes to button...but i been using only one button and for the apps I'm coding...will be using 4 I think that's why I needed to confirm! thanks

    BTW, where's Joeyd999!!? anyone one bumped into him in florida?:D He must be busy with his *sophisticated coding* and will probably come back with stories of his *inventions*:D...

    I once used his method (that I now understand as I read it several times) in one of my project...and it worked brilliantly BUT I almost failed coz no one could understand...even my instructor! LOL...I even had an argument with my instructor....bah bah bah...long story to put it here!

    I will post that project Im talking about here so you can have a look and get what I am saying...

    Alright!

    I am sure you have noticed I really *love* this all *microcontroller world* and all that goes with it...I am really willing to learn about MPLAB Sim, watch windows,...BUT I just can't find time! People at my school makin me work like I am a machine or a *consultant* already:D while I don't event know much... *but getting there;)*...

    But you are so right I sometimes have difficulties testing my codes as I still can't use Simulator...I debug with a pencil and paper and waste lots of time...
    Thanks a million Mike!
     
  7. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33
    I think I'll have a problem...all buttons must be in the same *PORTX* right, ?
     
  8. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    You use the HI-TECH C compiler? With this compiler it is not a problem working on bit level on any port. Which PIC do you plan to use
     
  9. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33
    I am using P16F690...using assembly! I'll just put them in PORTA as im using only 4 pushbuttons...can't move too much as I'm breadbording...I'm using an old project on breadboard and making a few changes to save time as I'll be spending more time on coding:)

    Also I correct to say that...that algorithm *up there* works for a *single* press at a time, huh!
     
  10. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    There is one key included for my LED matrix message tags.
    http://pic.hitechworld.org/data/ledmatrixtag/

    However, the key bit reading (on the hardware side),
    and the processing are seperated.
    Originally I derived this code in assembler language.

    The key handler is called in appreciate intervals,
    testing through all the hardware bits, and
    using a seperate key variable for each key.

    Later you also test all these key variables, process and reset if keys were pressed.

    This is all possible in assembler. However it is tedious, stretching over pages.

    If you code it hardware dependent, you may be able to get away with shorter assembler source. But it will be kind of bad code, means you need to change it each time for new circuits.

    One reason really to use C is that you can isolate hardware-independent code very easily. Once it works, you never need to change it again.

    I don't say "impossible in assembler". I have done it. But I know the result- many pages of source code.

    Maybe this information is superfluous. But the way I have outlined to test different keys using the same piece of code is good I think.

    Basically the different key bits are copied into a buffer (inside an 8bit file register). You could use parameters in C language. But it was done that way in assembler, and I did not see a good reason to change it.

    For the key counters only 2 bits are needed but full 8 bits registers are used.
     
    Eric007 likes this.
  11. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33
    I really like this!!!:)


    Humm...

    Very short! And I prefer to keep it short when possible.

    Why? coz the chanes you make are very small!


    Oh nice! but I want to be very good at assembly first before shifting to C.


    I know!:) but there are lots of jumps *goto or...* I have some huge codes but it *does NOT* necessarily means that all those lines are executed in sequences...I've had arguments about this and be marked down although everything works perfectly...:mad: I hate being stuck in a loop for example I'll have a couple of *return* for one single *routine* bah bah bah.....exit if its not time to be executed and check other stuff in the meantime or skip *return* when its time...and my instructor telling me 'you can't do that, only one entry and one exit'...I'm like WTF!!! you kidding me...it was long uglu discussion but did not want him to get too mad at me or else...:)

    I understand you!

    Ok!

    Yes Yes Yes!!!

    Thanks
     
    takao21203 likes this.
  12. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    I have a feeling you make this way to complicated. As I understand your project is to make clock. The most important thing here will be keeping the time. All that has to do with that, you put in the ISR. Less important things like updating the displays scanning the switches. You put outside the ISR. Use flags to tell the non ISR functionality that things need to be updated.
    Some tips! Then you are in the process of setting the time. Turn of the ISR. As it is not needed at that moment. Since you are doing this in assembler. Have a separate value for tenth of hours, minutes and seconds. Then you do not need to divide with ten any place.
     
    Eric007 likes this.
  13. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    In general, yes, there should be only one entry point as well exit point.
    However it sometimes turns out that it is easily possible to re-use a sequence of code, without a need for a seperate call. Especially interesting if you only have two stack levels.

    As for C return, it is not a syntax error to use multiple returns based on conditions (considering only one will be valid).

    It is a question of good coding practice. Sometimes you would use such constructs to save program space. Sometimes they are short and efficient.

    If possible, yes, only use one entry point/exit point.

    If you have to jump around 3 or 4 times, examine it carefully, if some of this logic can be removed, or spelled differently.

    It is called "procedural abstraction" I think. However, you do not have to follow such concepts literally or down to the point. Nearly anything that is possible in assembler also is possible in C.

    Functionality, Efficiency, code reuseability/maintainability, and good style are the factors to take care of. Sometimes you just put priority on one of them, and simply don't care the others. Sometimes the timing is so critical you have to resort to repeat long sequences of instructions, instead of calling a function.

    If neccessary (and giving a gain or good result), multiple entry points are perfectly good to use (and the same, multiple exit points). As for exit point, when I used assembler, in most cases I only used one. However in C even more removal of superfluous source lines is possible.
     
    Eric007 likes this.
  14. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33

    I understand you but everything need to be done, if I may say, at the same time..for instance setting the *current time* at run-time, setting the *alarm time* at run-time, displaying *alarm time* at run time...that's why I've titled my thread *multitasking...*

    I came up with a solution on paper that I have to code now...and Im running outa time...:( But Hopefully, I'll make it!

    * A little joke :)* do you realise that my last two thread are *interrupt routines* to my thread on *Chess robot* which is the *main function* ?:D:D

    These small *interrupts* are wasting my time BIG time...I need to focus on my *main* function

    End of joke!:D

    What a joke! :confused: I think I'm going crazy! lol
     
  15. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33
    I will comment on post #13 a bit later...as I need to lay down some code BUT thanks again and I always have *Functionality, Efficiency, code reuseability/maintainability* in mind when coding...
     
  16. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Well Eric good luck. It is still some time left. So I am sure you can make it. Your project is doable. But well you should perhaps have asked for help on a more early stage. Now you are kind of in panic mode. But also that can be a good thing. Be sure to get some sleep or your brain will turn into slush
     
    Eric007 likes this.
  17. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    I have an application that I am working on right now that requires the uC to sample an ADC (NTC Thermistor, which also converts value to Fahrenheit), and read 2 SPI Thermocouple to Digital converter IC's (MAX31855 and converts read values to Fahrenheit) and get the current time from DS1302 RTC which updates every second, and display all these values simultaneously on the LCD...... I also have 4 switches that I have to monitor a keypress from(I have those connected to PORTB and using the Interrupt on Change for that Port, the ISR just sets a flag called ButtonWasPressed when a switch is pressed)... after reading the ADC,SPI,and RTC I would check the ButtonWasPressed flag, if a button was pressed then I would jump into the main button press handler routine.... so all I have to monitor is the flag to indicate weather a button was pressed or not, and does not take too much time from the other routines it has to run.....

    Basically, it would have been easier to monitor these switches if they were all on the same port that are capable of generating an interrupt...
     
    Eric007 likes this.
  18. Eric007

    Thread Starter Senior Member

    Aug 5, 2011
    1,041
    33
    A quick question!

    one of my butons will display the alarm time for just small time! now I am wondering...what's the smallest delay I can set for the alarm so tat a human being can see?

    what I mean is on the press of the button, the display will show the *alarm time* for a quick period of time then display back the current time!

    thanks!
     
  19. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    That is not very important. If you have a time keeping ISR. You can show the alarm time as long as you want. This because the time keeping itselves will not be affected regardless of if you show the alarm time or the true time.
     
  20. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    I was faced with a similar problem when I designed the single chip Charlie Clock and I decided to use the <up> and <down> arrow keys to move between the Clock, Calendar, and Timer displays when in [Run] mode. Pressing the <set> switch toggles between [Run] and [Set] modes. Enter [Set] mode to edit the current display (clock, calendar, or timer) and use the <up> and <down> arrow keys to increment or decrement the current flashing display group (hours, minutes, or seconds, or, month, day, and year groups) and the <right> arrow key is used to move to the next display group. It's not nearly as complicated as it sounds.

    Good luck on your project.

    [​IMG]
     
    Last edited: Sep 8, 2012
    Eric007 likes this.
Loading...