PDA

View Full Version : Multi-Threading



Ted's
- 9th August 2008, 00:20
Is a 16f628a + pbp capable of multithreading? Is it capable of letting a led flash while proceeding another task to symbolize that it is busy?

mackrackit
- 9th August 2008, 00:43
Interrupts are the ticket.

This is pretty cool,
http://www.picbasic.co.uk/forum/showthread.php?t=3251

Ted's
- 10th August 2008, 14:38
What is the connection to my question? How do you create a program that lets a led flash while proceeding with another task to symbolize that it is busy using your interrupt thingy?

mackrackit
- 10th August 2008, 15:30
Well, the connection is... Multithreading is pretty much the same as an interrupt.
This may help you understand it a bit.
http://en.wikipedia.org/wiki/Thread_(computer_science)
So if someting tries to start another "task" an interrupt is flagged. How you do this or what you do with it is up to you.

Jumper
- 10th August 2008, 16:32
Hi,

If you look at the second post in this thread :

http://www.picbasic.co.uk/forum/showthread.php?t=3251&highlight=instant+interupt

you will see a code snippet that ALMOST does what you want to do. It has a main loop where it is just performing a pause and then a timer is setup to toggle the led.

This is very close to what you are asking for.. just enable the interupt before entering your task (so the led will start to flash) and when you exit your task disable it again.

If you change the preloaded value (and prescaler if you have to) for the timer you can have different fast flashing led depending what task you are performing...


This is not difficult because of the EXCELLENT code provided by DT.




LED1 VAR PORTB.1

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ToggleLED1, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM



goto main

my_task:
T1CON = $31 ; Prescaler = 8, TMR1ON to desice how fast we will flash

@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

;do all the stuff you want to do here

@ INT_DISABLE TMR1_INT ; DISABLE Timer 1 interrupts

RETURN


Main:
GOSUB my_task
PAUSE 10
GOTO Main

'---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN


This might ( I didn't compile and test it, and I am not sure if it is the right register for your PIC) work and should flash the LED while you are performing my_task only.. just remember if my_task is very fast you might come out of it before we flash since the LED is flashing once per sec or something now.

also we will go back to my_task every 10 sek... but what you do in your main loop I leave to you to decide.

/me

Ted's
- 10th August 2008, 16:52
This seems to be time critical, so if a pauseus is included the other task won't continue.

What I actually want to do is this: (see picture)(strongly abbreviated)

Down means LED is off, Up means LED is on. The x-axis represents time.

So it is a LED light - fader.

So time could be 100ms meaning the LED is being switched on successively in a repeating manner till it will have taken 50ms then the process is reversed amounting to a total of 100ms.

Can you suggest a code for this?

Jumper
- 10th August 2008, 17:36
To start with by using DT instant interupts the interupt will be performed no matter what the PIC is up to for the moment.. The PIC will stop in it tracks, do the interupt, toggle the led, return and then comtinue off where it was before.

First you wanted to flash a LED to show a busy task, now you want to fade a LED....

Is that one led or 255 leds or fading while doing other stuff..... I think I speak for more people than myself when I say "hmmm confused"..

What have you done previously, how much do you know about the PIC HW and what will your project do when it is done?

Good luck and I will keep an eye on this thread to see if I can help later on

mackrackit
- 10th August 2008, 17:42
I think I speak for more people than myself when I say "hmmm confused"..

Me too, sounds like this is going a different direction.

Ted's
- 10th August 2008, 20:30
First of all you have good English. We are talking about one led fading in and out which is being repeated. Imagine a flashing led. Now imagine the led is on. Imagine it not being on instantly but having an increase in brightness. Then imagine it having a decrease in brightness. Increase and decrease amount to flashing time. It softens the led's appearance.

Is that one led or 255 leds or fading while doing other stuff..... I think I speak for more people than myself when I say "hmmm confused"..

skimask
- 11th August 2008, 01:59
Is a 16f628a + pbp capable of multithreading? Is it capable of letting a led flash while proceeding another task to symbolize that it is busy?

You know and I know, based on previous performance, that nobody, anywhere, not today, not tomorrow, not ever, will be able to answer your questions to your satisfaction nor will you heed advice given to you by others...

But just in case....

No, PICs are not capable of multi-threading. None of them are. Period. Case closed. PICs cannot complete the execution of more than one single cycle instruction at any given time. Read it, learn it, live...
PC's up until about 10 years ago were never capable of multi-threading or multi-tasking as we think of the process today. They all used interrupts (either hardware or software) to switch tasks and/or memory space quickly enough that it seemed like they were running more than one program at a time.

It is very easy to, as you put it, fade and LED in and out, while running another program in a main loop, using interrupts. If I had a video of it, I would show you 20 RGB LEDs connected to a PIC18F8720, all doing something different, fading in/out, changing color, and so on and so on, while at the same time, displaying various debugging messages on an LCD, reading a 5 button keypad, reading a light 'program' from an SD card, communicating over a CP2103 USB link, and so on. All done with interrupts...not multi-tasking/-threading. All because it was being done so fast that it appeared to all be done at once. Slow down the oscillator speed to something very, very, slow and a person would be able to see (thru an ICD) the program executing different loops of code at different times.

That should be clear enough...but you'll probably refute every statement made above...and I'll probably 'un-refute' you at every turn....

Ted's
- 11th August 2008, 03:33
skimask, I recommend to you to read the other posts and my replies.

To me an interrupt means:

-Stop the current main program.
-Execute the interrupt routine
-Go back to where you came from in the main routine.

Basically interrupts should show a possible way to create the impression of multithreading. But.

But imagine there is a servo motor. The motor needs a signal every 20ms to keep it's torque. So the interrupt starts the interrupt routine. The interrupt routine should take say 2 seconds. And within these two seconds there is the action of force onto the motor.

This is what I was alluding to when writing about the pauseus issue. This stands for reserving time within the interrupt routine.

Or do DT's includes make the pic execute the code (even the main code) by cycling through each interrupt each cycle of code execution? So using a 20Mhz quarz leads to processing a portion of each code every 0.2 us?

I appreciate that you want to answer my questions to my satisfaction. Then give me a code example showing how to do that with DT's includes.

skimask
- 11th August 2008, 04:27
skimask, I recommend to you to read the other posts and my replies.
Hey, Good Idea! Why didn't I think of that....


To me an interrupt means:

-Stop the current main program.
-Execute the interrupt routine
-Go back to where you came from in the main routine.

Basically interrupts should show a possible way to create the impression of multithreading. But.

So far, so good...


But imagine there is a servo motor. The motor needs a signal every 20ms to keep it's torque. So the interrupt starts the interrupt routine. The interrupt routine should take say 2 seconds. And within these two seconds there is the action of force onto the motor.

This is what I was alluding to when writing about the pauseus issue. This stands for reserving time within the interrupt routine.

Or do DT's includes make the pic execute the code (even the main code) by cycling through each interrupt each cycle of code execution? So using a 20Mhz quarz leads to processing a portion of each code every 0.2 us?
You're thinking too linearly...stuck inside a box.
Keep track of a timer/counter that gets tipped much faster than every 20ms. Hit the servo, wait 20ms later (and servo's don't NEED exactly 20ms), hit the servo again.
If those LEDs I eluded to earlier miss a pulse completely, I'll see flickering. If one of those pulses is just a bit off, I most likely won't see anything...but quite frankly, they're solid, nice and smooth. So, from THAT programming standpoint, there isn't much of a difference between LEDs and Servos. Interrupts work great for me and a load of other people. You aren't any different.


I appreciate that you want to answer my questions to my satisfaction. Then give me a code example showing how to do that with DT's includes.
I don't want to. Just making a point based on your last 'thread' (if we can call it that)....
And it's YOUR job to give US a code example of how to do anything with DT's Instant Interrupts...and WE will HELP YOU figure out why it doesn't work the way YOU want it to work.
And what's wrong with the examples in the instant interrupt threads?

Darrel Taylor
- 11th August 2008, 05:24
And what's wrong with the examples in the instant interrupt threads?
I'd like to know that too. :eek:
<br>

Jumper
- 11th August 2008, 09:47
So we have one led you want to flash in a fading way.

How frequently do you want to flash it?

Do you want to do other stuff while flashing the LED? In that case what will the PIC do?

Can you put the LED on PORTB.3?

How fast do you want to fade it up and down?

How smooth do you need it, how many steps would you like the led to have on the way up and down?


Before we even try to untangle the code for this it would be nice to know that you can use this pin and get the other information as well.

/me

skimask
- 11th August 2008, 13:57
Can you put the LED on PORTB.3?
I'd doubt it...
http://www.picbasic.co.uk/forum/showthread.php?t=9275
Check post #32 and #33!

Ted's
- 27th August 2008, 23:23
Jumper if you want to design a code example do not stick to values, stick to variables instead. Frequency should be f. Other concurrent thread(s) exist while fading in/out. There is no data available about them yet. Just use "LED", I'll use a pointer to the right port like LED VAR PORTX.Y. Speed of fading should be a function of frequency. Freqency means: every 1/f seconds there is a change. If LED is off, Led_fade_routine starts and vv. Led_fade_routine consists of fade_in_time = 2/f and fade_out_time = 2/f. Smoothness depends on OSC. Should be as smooth as possible, ie chunks_duration should be at a minimum.

Thanks for your initiative. I appreciate that.

Jumper
- 28th August 2008, 09:51
Did I miss something? In my code example I have LED as an alias for a port and I can't see I use any other values than T1CON (which is a register).

If you are referring to my question about moving the LED to PORTB.3 it is only because I wanted to know if it was possible, and in that case we could use the HPWM for the fading. Doing that way would take very little instruction time and still give a nice fading effect since we only need to change the dutycycle once in a while to get a very smooth fading effect.

I am deeply sorry that my poorly written code example upset you.

over and out

/me

Melanie
- 28th August 2008, 13:49
Ted stop winding people up that are trying to help you. Folks give up their time for free around here. If you don't like an answer then be polite, say "Thank You" to acknowledge the time they may have devoted to potentially a lost cause, and move on.

In case you're not aware... the short answer to your question at Post #1 is Yes.

If yor PIC has ADC, Comparators, CCPM, USART etc the you can SIMULTANEOUSLY perform any or all of those functions whilst doing something else altogether AT THE SAME INSTANT IN TIME. Go do a forum SEARCH, this has been discussed before.

Alternatively you can TIME-SLICE your code... in the simplest form, using your flashing LED for example, say the LED is flashing at a 2Hz rate, you can switch ON your LED, then go do something else for 250mS before you need to devote an instruction to switching it OFF Gee... at 4MHz, that's a shed load of instructions you can carry out whilst that LED is ON, and again when it's OFF. To the casual observer, it will appear as if the PIC is doing multiple tasks.

peterdeco1
- 28th August 2008, 18:34
How would you use the ADCIN command to read the value of a pot while simultaneously doing something else?

Bruce
- 28th August 2008, 19:17
Setup a hardware peripheral like capture, hardware PWM, counter, UART, etc and enable
it. They will all run simultaneously in the background while you're sampling the A/D input.

Security
- 2nd September 2008, 04:18
Hello. I am using the instant interrupt routine. I also posess a servo motor like ted,
so I wand to start a pulsout every 20ms. I did this in the tmr0-interrupt routine(tmr0
initialized by OPTION_REG = 1) I am using a 20Mhz quarz.

I think: 20 / 4 = 5Mhz. OPTION_REG means prescaler = 1:1. Means 1/(5,000,000) equals 0.2us.

TMR0 = 8Bit => 256 * 0.2us = 51.2us.

So every 51.2us there will be an interrupt. So

20,000 / 51.2 = 390.625 = 391. So as soon as the interrupt will have occurred 391 times 20ms
should have been passed. I wrote


main:
'...do xyz
counter = 0
END

IRRoutine:
IF counter = 391 THEN
pulsout servo, duration
ENDIF
IF counter > 391 THEN
counter = 0
ENDIF
IF counter < 391 THEN
counter = counter + 1
ENDIF
@ INT_RETURN

But the servo is choppy. What is wrong?

skimask
- 2nd September 2008, 04:59
How does this work?


main:
'...do xyz
counter = 0
END

IRRoutine:
IF counter => 391 THEN
pulsout servo, duration
counter = 0
ELSE
counter = counter + 1
ENDIF
@ INT_RETURN

Security
- 2nd September 2008, 05:55
Well.

But the servo is still choppy.

I found the reason: Option_reg was wrong. I had a prescaler of 2:1.