Log in

View Full Version : DT Instant Interrupts



krohtech
- 9th February 2008, 02:45
Hello All,

Darrel,

I love the Instant Interrupts. Is it possible to use it with multi SPWM? I need a system LED that just blinks at a constant speed like 4 times a second. to show that the pic is working.

Darrel Taylor
- 9th February 2008, 05:06
Is it possible to use it with multi SPWM?
I rewrote the old SPWM module to work with DT_INTS some time ago.

DT_INTS-14 (SPWM_INT - Multiple Software PWM)
http://darreltaylor.com/DT_INTS-14/SPWM.html

But if you just want to blink an LED at a certain rate, the Timer Template might be more appropriate.

DT_INTS-14 (Timer Template)
http://darreltaylor.com/DT_INTS-14/TimerTemplate.html
<br>

krohtech
- 9th February 2008, 05:53
Oh, sorry I forgou to mention I am using an 18F PIC. Can I use the timer template -14?

skimask
- 9th February 2008, 06:10
Oh, sorry I forgou to mention I am using an 18F PIC. Can I use the timer template -14?

You're talking about one of my favorite 'staples' whenever I build something...I call it a 'heartbeat'...
I have an LED connected to a specific pin...
I set up Timer 0 to run at a decent rate according to my main clock speed...i.e. once per second-ish, 4 times per second-ish, doesn't really matter, as long as I can see it blink.
Then every Timer 0 overflow, I increment a byte variable, last I set the LED to follow a certain bit of that variable.
So, say I use 'temp' as my variable.
myint:
temp = temp + 1
led = temp.0 'led will flash on/off every other time thru loop
resume

If the LED flashes too fast, I use temp.1, still too fast, maybe temp.2.
Or, conversely, if I use temp.4, and that flash is too slow, I'll use temp.3, or temp.2, whatever...until I find a flash rate that works for me.

DT's Fast interrupts and SSPWM code are great pieces of code...but I think they're big time overkill for what you want...

An example cut from one of my last programs:


'CONFIG statements semi-permanently set in PBP 18F4620 .INC file
resetplaceholder: '18f4620 code
DEFINE OSC 10
DEFINE NO_CLRWDT 1 'no extra clear watchdog timer instructions
DISABLE
CLEAR
led1 var porta.5
heartbeat var byte
startupholder:
goto skipsubs 'skip over all the commonly used subroutines
ON INTERRUPT GOTO INTHANDLER
DISABLE
INTHANDLER: if intcon.2 = 1 then 'timer 0 overflow interrupt handler
intcon.2 = 0
heartbeat = heartbeat + 1
led1 = heartbeat.0 'led flash about every ~1.6 seconds
' change heartbeat.0 to heartbeat.X where x = 0 - 7 to change heart beat flash rate
INTFINISH:
RESUME
DISABLE
'end of commonly used subroutines, skipsubs block for setting up registers, lcd, whatever else...
skipsubs:
t0con = $84
intcon = $e0
cmcon = 7
pie2 = $80
trisa = 0
porta = 0
led1 = 0
output led1
' change prescale value in $84 to change flash rate
ENABLE
mainloop:
' do something useless or useful here
goto mainloop
END

IF you're not using a '4620, then you'll have to figure out which registers need which values as far as interrupt and timer registers go.
I chose porta.5 because it was available. Change that to what you need also.

Darrel Taylor
- 9th February 2008, 06:48
I need a system LED that just blinks at a constant speed like 4 times a second. to show that the pic is working.

&nbsp; ... and ...

Oh, sorry I forgou to mention I am using an 18F PIC. ...
I'm thinking just the Blinky example is all you need.

DT_INTS-18 (Blinky Light)
http://darreltaylor.com/DT_INTS-18/blinky.html

Or, even better ...

DT_INTS-18 (Assembly Language Interrupts)
http://darreltaylor.com/DT_INTS-18/asm_ints.html

Same Blinky LED, without the Basic Language Interrupt overhead. :cool:

And no running Colon's :p
<br>

krohtech
- 9th February 2008, 07:07
DT_INTS-18 (Assembly Language Interrupts)
http://darreltaylor.com/DT_INTS-18/asm_ints.html



Yes, this is the code I am using but I can't get it working in the same program as the multi SPWM. I am useing multi SPWM for my 8 pwm dimmers.

Also I have played with the prescaler to slow down the blink rate but have had no sucess. is there a formula for this like in the -14 version?

I will also make an attempt to digest Skymask's timer 0 overflow interrupt handler in the morning.

Thanks Darrel and Skymask. You are both very helpful.

Darrel Taylor
- 9th February 2008, 07:32
The original SPWM will not work with Instant Interrupts.
They both want complete control of the interrupts. (can't happen)

However, SPWM_INT will work with Instant Interrupts.
And yes, the version shown in the -14 section will work on the 18F's too.

DT_INTS-14 (SPWM_INT - Multiple Software PWM)
http://darreltaylor.com/DT_INTS-14/SPWM.html

SPWM_INT uses Timer1, so if you also want a Blinky light, you'll need to use a different Timer. (0, 2 or 3)

And if you want to use either of the SPWM versions, then you can't use skimask's code.
They are not compatible with ON INTERRUPT.
<br>

skimask
- 9th February 2008, 07:59
And if you want to use either of the SPWM versions, then you can't use skimask's code.
They are not compatible with ON INTERRUPT.
<br>

And if you want my opinion (nobody really does, but that's beside the point), you'd do real good to learn how to use DT's Instant Interrupt's instead of relying on PBP's On Interrupt.
It's not only good coding with good applications, you just plain learn a lot in the process...and then you spend more money and more time on PICs and PBP and less time on...well, wait a minute...gotta eat sometime...right?

krohtech
- 10th February 2008, 18:50
I have SPWM_INT working really well. I am doing 16 ch of PWM on a pic 18F2410 32 MHz. The pwm is running at 100Hz 8 bit resolution.




SPWM_INT uses Timer1, so if you also want a Blinky light, you'll need to use a different Timer. (0, 2 or 3)
<br>

Here is where I am having trouble. I tried to add a blinky from the DT_INTS-18 example and change it to timer0 with no success. Darrel, can you point me in the correct direction?

krohtech
- 10th February 2008, 20:50
here is my current code, changed to 101 PWM resolution to reduce overhead



'-----------------------------SPWM INT-----------------------------
CLEAR

INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "SPWM_INT.bas" ; Software PWM module
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts

LED2 VAR PORTA.5

DEFINE SPWM_FREQ 100 ; SPWM Frequency
DEFINE SPWM_RES 101 ; SPWM Resolution

DutyVars VAR BYTE[16] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]
DutyVar4 VAR DutyVars[3]
DutyVar5 VAR DutyVars[4]
DutyVar6 VAR DutyVars[5]
DutyVar7 VAR DutyVars[6]
DutyVar8 VAR DutyVars[7]
DutyVar9 VAR DutyVars[8]
DutyVar10 VAR DutyVars[9]
DutyVar11 VAR DutyVars[10]
DutyVar12 VAR DutyVars[11]
DutyVar13 VAR DutyVars[12]
DutyVar14 VAR DutyVars[13]
DutyVar15 VAR DutyVars[14]
DutyVar16 VAR DutyVars[15]

ASM
SPWM_LIST macro ; Define Pin's to use for SPWM
SPWM_PIN PORTB, 0, _DutyVar1 ; and the associated DutyCycle variables
SPWM_PIN PORTB, 1, _DutyVar2 ; Notice the underscore before variables
SPWM_PIN PORTB, 2, _DutyVar3
SPWM_PIN PORTB, 3, _DutyVar4
SPWM_PIN PORTB, 4, _DutyVar5
SPWM_PIN PORTB, 5, _DutyVar6
SPWM_PIN PORTB, 6, _DutyVar7
SPWM_PIN PORTB, 7, _DutyVar8
SPWM_PIN PORTC, 0, _DutyVar9
SPWM_PIN PORTC, 1, _DutyVar10
SPWM_PIN PORTC, 2, _DutyVar11
SPWM_PIN PORTC, 3, _DutyVar12
SPWM_PIN PORTC, 4, _DutyVar13
SPWM_PIN PORTC, 5, _DutyVar14
SPWM_PIN PORTC, 6, _DutyVar15
SPWM_PIN PORTC, 7, _DutyVar16
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
INT_Handler TMR0_INT, _ToggleLED2, PBP, yes

endm
INT_CREATE ; Creates the interrupt processor
ENDASM

T0CON = %10010010 ; T0 = 16-bit, Prescaler 8
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
@ INT_ENABLE TMR0_INT ; enable Timer 0 interrupts


'-----------------------------Main Program-----------------------------
Main:

Darrel Taylor
- 10th February 2008, 21:21
I think the Cut&Paste didn't catch everything.

Can you post the Main: and Handler parts?
Thanks.

Darrel Taylor
- 10th February 2008, 22:00
OH!, nevermind!

ADCON1 = $0F

:p

krohtech
- 10th February 2008, 22:45
Thanks Darrel,

That worked, I think I need to learn that register, TIME TO HIT THE DATA SHEET...

Darrel Taylor
- 10th February 2008, 23:08
That's a good one to learn.
You'll need some variation of it in almost every program you write.

Also, Since the TMR0_INT handler is only toggling a pin, it's not using any PBP system variables.

You can change the TMR0_INT's "Type" to ASM.
Then it won't be saving all the system variables when it doesn't need to. Time is critical with that many simultaneous PWM's.

Then you can remove the ReEnterPBP-18.bas include file, which will save some RAM and Code space.

krohtech
- 11th February 2008, 05:25
Thanks again Darrel,

I just fully tested the SPWM_INT running 16 channels @ 100Hz 0-100 resolution. I tested each channel with a 7 amp led cluster (Agilight Brightstrip see below) of typical sign led strips powered through a MOSFET. This worked great. I am able to dim all the way down to 1% without any flicker and smoothly fade up to 100% with no flicker or noticeable stair stepping effect. This is smoother than when I used the older multi SPWM program.

I really appreciate you help

http://www.agilight.com/brightstrip/index.htm

Darrel Taylor
- 11th February 2008, 08:07
Great Testimonial Kurt!

Mind if I use it on my website?
<br>

Ioannis
- 11th February 2008, 13:20
...
You can change the TMR0_INT's "Type" to ASM.
Then it won't be saving all the system variables when it doesn't need to. Time is critical with that many simultaneous PWM's.

Then you can remove the ReEnterPBP-18.bas include file, which will save some RAM and Code space.

I may missed that little but critical details. Are these described somewhere Darrel?

And may be others too that I am not aware off...

Thanks,
Ioannis

krohtech
- 11th February 2008, 17:37
Great Testimonial Kurt!

Mind if I use it on my website?
<br>

Darrel,

Feel free to use my testimonial in any way you see fit.

Darrel Taylor
- 11th February 2008, 20:21
Thanks Kurt!

Ioannis,

I've mentioned it a couple times here in the forum, but I just spent about an hour trying to find them, and failed.

I really should write some more pages for the website.

Anyone got a Cloning Machine? I need another Me. :)

krohtech
- 13th February 2008, 22:14
Hay Darrel,

In the DT_INTS-14 (SPWM_INT - Multiple Software PWM) It says:



DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]


I do not know how to use arrays or how it can benefit in loops. The way I am doing it now is very cumbersome and code intensive. I have searched the forum and RTFM but I can't get my head around how this concept. Can anyone point me in the correct direction.

Darrel Taylor
- 13th February 2008, 22:23
If you wanted to set all LED's to the same brightness, you could ...


LoopCount VAR BYTE

FOR LoopCount = 0 to 15 ; 16 channels
DutyVars(LoopCount) = 50 ; 50% (0-100)
NEXT LoopCount

<br>

Archangel
- 13th February 2008, 22:50
If you wanted to set all LED's to the same brightness, you could ...


LoopCount VAR BYTE

FOR LoopCount = 0 to 15 ; 16 channels
DutyVars(LoopCount) = 50 ; 50% (0-100)
NEXT LoopCount

<br>Hi Darrel,
could you please explain DutyVars(LoopCount) = 50 ; 50% (0-100), I understand the counter loop but do not understand the operation here. Thank You
JS

krohtech
- 13th February 2008, 23:25
Hi Derrel,

Thanks for the code, Unfortunately I was hoping for something that would allow me to set different values to the duty cycle of each channel. The way I have it configured I use CH# as the var name:



DEFINE SPWM_FREQ 100 ; SPWM Frequency
DEFINE SPWM_RES 101 ; SPWM Resolution

DutyVars VAR BYTE[16] ; DutyCycle Variables
CH1 VAR DutyVars[0] ; group them in an array for easy access
CH2 VAR DutyVars[1] ; with FOR loops etc.
CH3 VAR DutyVars[2]
CH4 VAR DutyVars[3]
CH5 VAR DutyVars[4]
CH6 VAR DutyVars[5]
CH7 VAR DutyVars[6]
CH8 VAR DutyVars[7]
CH9 VAR DutyVars[8]
CH10 VAR DutyVars[9]
CH11 VAR DutyVars[10]
CH12 VAR DutyVars[11]
CH13 VAR DutyVars[12]
CH14 VAR DutyVars[13]
CH15 VAR DutyVars[14]
CH16 VAR DutyVars[15]


and change the duty in this manor:



Main:
gosub CKINPUT

CH1 = 100
CH2 = 0
CH3 = 0
CH4 = 0
CH5 = 0
CH6 = 0
CH7 = 0
CH8 = 0
CH9 = 0
CH10 = 0
CH11 = 0
CH12 = 0
CH13 = 0
CH14 = 0
CH15 = 0
CH16 = 0
gosub CKINPUT
PAUSE T5
CH1 = 100
CH2 = 100
CH3 = 0
CH4 = 0
CH5 = 0
CH6 = 0
CH7 = 0
CH8 = 0
CH9 = 0
CH10 = 0
CH11 = 0
CH12 = 0
CH13 = 0
CH14 = 0
CH15 = 0
CH16 = 0
gosub CKINPUT
PAUSE T5


and so on... If anyone can suggest a better method I would be very interested in learning better ways to program.

skimask
- 14th February 2008, 17:39
DEFINE SPWM_FREQ 100 ; SPWM Frequency
DEFINE SPWM_RES 101 ; SPWM Resolution
DutyVars VAR BYTE[16] ; DutyCycle Variables
CH1 VAR DutyVars[0] ; group them in an array for easy access
CH2 VAR DutyVars[1] ; with FOR loops etc.
...............
CH15 VAR DutyVars[14]
CH16 VAR DutyVars[15]

and change the duty in this manor:


Main:
gosub CKINPUT
CH1 = 100
CH2 = 0
............
CH15 = 0
CH16 = 0
gosub CKINPUT
PAUSE T5
CH1 = 100
CH2 = 100
CH3 = 0
CH4 = 0
...........
CH15 = 0
CH16 = 0
gosub CKINPUT
PAUSE T5

and so on... If anyone can suggest a better method I would be very interested in learning better ways to program.

I don't see what the problem is...
You've already got CH1 an as alias to DUTYCYCLE[0]...therefore:
CH1 = 0 (or whatever)
is equal to
DUTYCYCLE[0] = 0 (or whatever)
They are functionally equivalent....

Therefore, if you had to use a loop:

for temp = 0 to 16 : dutycycle[ temp ] = 0 : next temp

would be equal to

ch1 = 0
ch2 = 0
and so on until....
ch15 = 0
ch16 = 0

krohtech
- 14th February 2008, 19:54
Hi Skymask,

Maybe I can clarify what I am trying to do. I didn’t post my entire code because it is very long. I will attach as a text file. I am designing a sign controller AKA sign animator AKA sign speller. What I need to do is CH1 ON pause X, add CH2 on Pause X, add CH3 pause X … This is an oversimplification but you can get the idea. It will allow me to program patterns left to right, right to left, center out, outside in, fade from left to right etc.

I guess I was hoping for was some kind of nested for next loop with an array?

I probably am not phrasing it correctly as I am a beginning programmer. Most of my experience is in programming large theatrical RGB lighting clusters which is not really programming in the same use of the word. I really haven’t “written code” since high school.

I do appreciate all the help and am enjoying the journey!!!

skimask
- 14th February 2008, 20:31
Hi Skymask,
Maybe I can clarify what I am trying to do. I didn’t post my entire code because it is very long. I will attach as a text file. I am designing a sign controller AKA sign animator AKA sign speller. What I need to do is CH1 ON pause X, add CH2 on Pause X, add CH3 pause X … This is an oversimplification but you can get the idea. It will allow me to program patterns left to right, right to left, center out, outside in, fade from left to right etc.
I guess I was hoping for was some kind of nested for next loop with an array?
I probably am not phrasing it correctly as I am a beginning programmer. Most of my experience is in programming large theatrical RGB lighting clusters which is not really programming in the same use of the word. I really haven’t “written code” since high school.
I do appreciate all the help and am enjoying the journey!!!

Where do you plan on storing all of this data? On chip eeprom, program memory, off chip serial eeprom, CF card?
I can see using a FONT table to store all of the characters, each character being a mini-array of points. Then depending on how you read out those points from that array, it may look like the character is shifting left/right/up/down, whatever.

I think you need to setup an array of data and do matrix operations on that array when dealing with the full screen.
I.E.
4 x 4 array = 16 data points, array var byte[16]
x / y = 4 / 4 = 16
point 0,0
x + (y*4) = point in array, in this case point 0, first byte in array
point 3,3
x + (y*4) = point in array, in this case point 15, last byte in array
PBP doesn't do multi-dimensional arrays but you can easily overcome that with some simple math.

krohtech
- 15th February 2008, 00:13
Thanks Skimask

I will have to play with this to absorb it. I will give it a try this weekend.

krohtech
- 15th February 2008, 00:20
Where do you plan on storing all of this data? On chip eeprom, program memory, off chip serial eeprom, CF card?

I was planning on storing the data in the program memory as it will probably not need to be changed once the sign is installed.

Darrel Taylor
- 15th February 2008, 00:47
I guess I was hoping for was some kind of nested for next loop with an array?
I don't know if I can explain the whole Arrays and Loops category. Would need a full book.

But here's some more examples (untested) that might nurture some thoughts.

Value VAR BYTE
X VAR BYTE
Y VAR BYTE
MarqueeCnt VAR BYTE
RepeatCnt VAR BYTE
Rnd VAR WORD : Rnd = 123

MaxChannel CON 15

Main:
Value = DIM
GOSUB ALL2Value
Pause 2000
GOSUB Marquee
GOSUB Scan
GOSUB DoRandom
GOTO Main

;------------------------
Marquee:
Value = 0
Gosub ALL2value
For RepeatCnt = 1 to 50
MarqueeCnt = (MarqueeCnt + 1) // 4
For X = 0 to MaxChannel STEP 4
For Y = X to X + 3
Lookup ((Y-X) + MarqueeCnt),[0,25,75,25,0,25,75,25],Value
DutyVars(Y) = Value
Next Y
Next X
Next RepeatCnt
Return


;------------------------
Scan:
Value = 0
Gosub ALL2value
For RepeatCnt = 1 to 20
For X = 0 to MaxChannel
DutyVars(X) = MED
Pause 200
DutyVars(X) = 0
Next X
Next RepeatCnt
Return


;------------------------
DoRandom:
For RepeatCnt = 1 to 100
For X = 0 to MaxChannel
RANDOM Rnd
DutyVars(X) = Rnd // 100
Next X
Pause 200
Next RepeatCnt
Return

;------------------------
ALL2value:
For X = 0 to MaxChannel
DutyVars(X) = Value
Next X
Return

HTH,

krohtech
- 15th February 2008, 03:54
I don't know if I can explain the whole Arrays and Loops category. Would need a full book.

Can anyone recomend a good book on PBP or BASIC that may help with the finer points of arrays and loops etc. I am very willing to read and research to learn more.


Thanks Darrel,

I will have more time this weekend to try this.

skimask
- 15th February 2008, 03:58
Can anyone recomend a good book on PBP or BASIC that may help with the finer points of arrays and loops etc. I am very willing to read and reserarch to learn more.
Thanks Darrel,
I will have more time this weekend to try this.

I don't think there really is such an animal as a book that would explain the finer points of loops/arrays, and such, and except for some oddball things about PBP variables (indexing and such), I'm kinda thinking that there aren't any finer points of loops and arrays.
I think this is one of those cases when you have to play with the structure of the loops and arrays until you get it how you like it and can understand it the best, whether you pull the data from eeprom, or make it up on the spot or whatever.
I think it boils down to your 'coding style' (many think my 'coding style' sucks for instance because I use too many colons).
There are lots of good books on coding, I haven't read any of them :) (refer to the earlier statement about coding style).

Archangel
- 15th February 2008, 06:03
Hi Darrel,
could you please explain DutyVars(LoopCount) = 50 ; 50% (0-100), I understand the counter loop but do not understand the operation here. Thank You
JS
Anybody ???

skimask
- 15th February 2008, 06:14
Anybody ???

Nothing more than an index'd variable.

DutyVars(LoopCount) = 50

(not code below...)
If loopcount = 1 then the following two lines are equivalent

-DutyVars(1) = 50

-loopcount = 1 : DutyVars(loopcount) = 50

At least I think that's what you were asking about.
If that's what you were asking, the book explanation is in Chapter 4.5 of the manual...if not...whoops! My bad :)

Archangel
- 15th February 2008, 06:52
OK, so dutyvars is an array holding the changing value loopcount and that = 50 ? This really is Fuzzy . . .

label VAR size[number of elements]
label = DutyVar
size = Loopcount
what does = 50 do exactly?
Does it give you a 16 byte array all having the value of 50?

krohtech
- 15th February 2008, 07:46
what does = 50 do exactly?
Does it give you a 16 byte array all having the value of 50?



Hi Joe,

50 would be the duty cycle of the PWM. In this example the SPWM_INT duty cycle was setup to be 0 - 100 so 50 would be roughly 50% at 100 Hz. See Below



DEFINE SPWM_FREQ 100 ; SPWM Frequency = 100 Hz
DEFINE SPWM_RES 101 ; SPWM Resolution = 0-100

Archangel
- 15th February 2008, 07:57
Hi Joe,

50 would be the duty cycle of the PWM. In this example the SPWM_INT duty cycle was setup to be 0 - 100 so 50 would be roughly 50% at 100 Hz. See Below
Hi Kurt,
I understood what the 50 stands for, but not what the array does or how it does it, does it set all PWM outputs to 50 % ? I am thinking that is what it does.
Thanks
JS

krohtech
- 15th February 2008, 08:18
Hi Kurt,
I understood what the 50 stands for, but not what the array does or how it does it, does it set all PWM outputs to 50 % ? I am thinking that is what it does.
Thanks
JS

Hi Joe,

Yse in this example it does set all 16 channels to 50.

boroko
- 3rd January 2009, 21:15
Hi Kurt, (and all)

In post #10, you mentioned that you used a different PWM resolution of 101 instead of 100. Can you expand on that a bit? I'm working on something similar and would like to understand why that helps.


"here is my current code, changed to 101 PWM resolution to reduce overhead"

Thanks
Mark

boroko
- 25th February 2009, 15:33
Just wondering if anyone knew why that resolution of 101? Kurt must have missed my question.

Thanks
Mark