Re: Linear acceleration ramp
I don't know if it will execute quickly enough but you could use a lookup table in a for next loop where the counter VAR is the lookup VAR.
example:
for i = 0 to 10
lookup i,[10,25,50, . . . . ] pulsevar
next i
Re: Linear acceleration ramp
Although you said linear, I assume you really can live with a staircase.
If that's the case, and I understand the question correctly, then it's just simple math.
Your example: ramp from 10 (x) to 560 (y) in 42 seconds (n).
Suppose you want 1 step per second. In that case:
stepsize = (y-x)/n
output = x
FOR QQ = 1 to n
PAUSE 1000
output = x + stepsize
next QQ
Replace the pause with a 1 second interrupt if you need to do other things.
"output" feeds yout DAC
Re: Linear acceleration ramp
Quote:
Originally Posted by
Charlie
Although you said linear, I assume you really can live with a staircase.
If that's the case, and I understand the question correctly, then it's just simple math.
Your example: ramp from 10 (x) to 560 (y) in 42 seconds (n).
Suppose you want 1 step per second. In that case:
stepsize = (y-x)/n
output = x
FOR QQ = 1 to n
PAUSE 1000
output = x + stepsize
next QQ
Replace the pause with a 1 second interrupt if you need to do other things.
"output" feeds yout DAC
I will try that, thanks!
Re: Linear acceleration ramp
On problem is the rounding error you will get with (y-x)/n
In your example: (560-10)/42 = 13.09524
But, PBP will only see 13. So, at the end of your routine, you will end up with 10 + (42*13) = 556
You will need to put in one line at after Next QQ:
Output = y
Re: Linear acceleration ramp
Here is another alternative: Vary the period you increment your speed.
This examply uses PAUSE.
Code:
Incr_Time_ms = (1000 * Duration) / (End_Val - Start_Val)
Current_Val = Start_Val
Do Until Current_Val = End_Val
PAUSE Incr_Time_ms
Current_Val = Current_Val + 1
Loop
What would be ideal is set up a timer and add a value so that it overflows after "Incr_Time_ms". You can then use interrupts, or just poll the flag bit. increment your "Current_Val", clear the flag bit, and then add the value to set up the overflow after "Incr_Time_ms". Wash-Rinse-Repeat until "Current_Val = End_Val"
Re: Linear acceleration ramp
Quote:
Originally Posted by
SteveB
Here is another alternative: Vary the period you increment your speed.
This examply uses PAUSE.
Code:
Incr_Time_ms = (1000 * Duration) / (End_Val - Start_Val)
Current_Val = Start_Val
Do Until Current_Val = End_Val
PAUSE Incr_Time_ms
Current_Val = Current_Val + 1
Loop
What would be ideal is set up a timer and add a value so that it overflows after "Incr_Time_ms". You can then use interrupts, or just poll the flag bit. increment your "Current_Val", clear the flag bit, and then add the value to set up the overflow after "Incr_Time_ms". Wash-Rinse-Repeat until "Current_Val = End_Val"
Hi Steve,
I've used what you said, and I've also included a deceleration ramp:
(sorry for renaming the values, it's for a easier integration in my main program).
Code:
' PIC18F4431 initialization
DEFINE OSC 40
DEFINE LCD_DREG PORTD
DEFINE LCD_EREG PORTB
DEFINE LCD_RSREG PORTB
DEFINE LCD_EBIT 6
DEFINE LCD_RSBIT 7
tacc var BYTE
tdec var BYTE
cacc var word
cdec var word
ref var word
fmin var word
freq var WORD
tacc=1
tdec=10
fmin=10
ref=1200
PAUSE 4000
LCDOUT $fe,$1
cacc = (1000 * tacc) / (ref - fmin)
cdec = (1000 * tdec) / (ref - fmin)
lp:
if freq<ref then PAUSE cacc
if freq>ref then PAUSE cdec
if freq<ref then freq = freq + 1
if freq>ref then freq = freq - 1
LCDOUT $fe,$2,DEC5 freq
if PORTC.0=%1 then ref=500
goto lp
It works quite good, but I cannot exeed 65 seconds (because 66*1000=66000, 16-bit integer is overflowed).
But, more importantly, I want to integrate the loop in a low priority DT interrupt. I really don't understand how you're using flags, etc. (I'm a beginner lol).
Thanks
1 Attachment(s)
Re: Linear acceleration ramp
Here is a start (not tested!). But it should get you going in the right direction. I only included the acceleration stuff to keep the logic simpler.
You will need the include files (Get Darrel's from http://darreltaylor.com/DT_INTS-18/downloads.html), and make sure the file names match.
Code:
' PIC18F4431 initializationDEFINE OSC 40
DEFINE LCD_DREG PORTD
DEFINE LCD_EREG PORTB
DEFINE LCD_RSREG PORTB
DEFINE LCD_EBIT 6
DEFINE LCD_RSBIT 7
tacc var BYTE
tdec var BYTE
cacc var word
cdec var word
ref var word
fmin var word
freq var WORD
cacc_div VAR BYTE
cdec_div VAR BYTE
tacc=1
tdec=10
fmin=10
ref=1200
PAUSE 4000
LCDOUT $fe,$1
INCLUDE "DT_INTS-18.bas"
INCLUDE "ReEnterPBP-18.bas"
INCLUDE "TimerControl.pbp" ; Timer Control Routines
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _UpdateTickCount, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
GOSUB ResetTime ' Reset Timer and mSec_Ticks = 0
IF tacc > 65 THEN
cacc_div = 10
ELSE
cacc_div = 1
ENDIF
cacc = ((1000/cacc_div) * tacc) / (ref - fmin)
GOSUB StartTimer ' Start Counting mSec_Ticks
Main:
IF mSec_Ticks > (cacc * cacc_div) THEN
IF freq < ref THEN freq = freq + 1
mSec_Ticks = mSec_Ticks - (cacc * cacc_div)
IF freq >= ref THEN
GOSUB StopTimer
GOSUB ResetTime
ENDIF
LCDOUT $fe,$2,DEC5 freq
IF PORTC.0=%1 THEN ref=500
GOTO Main
I may not be much use the next couple of days, but the building blocks are here (hopefully without too many errors/typos)
Re: Linear acceleration ramp
Quote:
Originally Posted by
pxidr84
Hi Steve,
It works quite good, but I cannot exeed 65 seconds (because 66*1000=66000, 16-bit integer is overflowed).
But, more importantly, I want to integrate the loop in a low priority DT interrupt. I really don't understand how you're using flags, etc. (I'm a beginner lol).
Thanks
Use a long for your variable - you'll have to work hard to overflow 32 bits.
Re: Linear acceleration ramp
Thanks for mentioning that Charlie! (I forgot too)
It would certainly simplify the code. I went with the non-LONG method in the case that Pxidr84 might not have PBP3, and so no LONG variables. But yes, I would definitely use them if available. Either way, hopefully the methodology of the example is instructive in learning to scale integers to fit into the given variable space.
Also, there is a correction I need to make to the code. I forgot an ENDIF:
Code:
IF mSec_Ticks > (cacc * cacc_div) THEN
IF freq < ref THEN freq = freq + 1
mSec_Ticks = mSec_Ticks - (cacc * cacc_div)
IF freq >= ref THEN
GOSUB StopTimer
GOSUB ResetTime
ENDIF
ENDIF
Sorry about that.
Re: Linear acceleration ramp
Quote:
Originally Posted by
SteveB
Thanks for mentioning that Charlie! (I forgot too)
It would certainly simplify the code. I went with the non-LONG method in the case that Pxidr84 might not have PBP3, and so no LONG variables. But yes, I would definitely use them if available. Either way, hopefully the methodology of the example is instructive in learning to scale integers to fit into the given variable space.
Also, there is a correction I need to make to the code. I forgot an ENDIF:
Code:
IF mSec_Ticks > (cacc * cacc_div) THEN
IF freq < ref THEN freq = freq + 1
mSec_Ticks = mSec_Ticks - (cacc * cacc_div)
IF freq >= ref THEN
GOSUB StopTimer
GOSUB ResetTime
ENDIF
ENDIF
Sorry about that.
I think that my PBP 2.6 support LONGs... I can't exceed 65s, but right now it's not important.
I've maybe find an another way (only for make a timer without PAUSE):
-Use a "fixed" frequency low priority interrupt
-Increment a value at each interrupt execution (for exemple, incr=incr+1)
-And execute the ramp code if "incr" as reached a certain calculated value (actually it's "cacc" and "cdec"), and then reset "incr" to zero.
Really, I don't need a nanosec precision for this ramp.
Re: Linear acceleration ramp
PBP 2.6 suppoerts LONGS with 18F devices. You just need to select "Use PBPL" for the compiler.
Re: Linear acceleration ramp
Quote:
Originally Posted by
pxidr84
-Use a "fixed" frequency low priority interrupt
-Increment a value at each interrupt execution (for exemple, incr=incr+1)
-And execute the ramp code if "incr" as reached a certain calculated value (actually it's "cacc" and "cdec"), and then reset "incr" to zero.
Did you see post # 8?
Re: Linear acceleration ramp
Quote:
Originally Posted by
SteveB
Did you see post # 8?
Yes I've see your post, but I've not tried it yet, I will do that today.