Searching \ for '[PIC]: pic changing program speed ?' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'pic changing program speed ?'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: pic changing program speed ?'
2001\04\03@085802 by Rob S

flavicon
face
part 1 780 bytes content-type:text/plain; charset="us-ascii"Hi,

I've been looking for two days at this strange problem now that I
encountered while making a little program to to rotate a stepper-motor.

The problem is that there are two timing loops in the program. The first
one determines the start-up delay, and the second one determines the
rotation speed. The first one does exactly what i calculated, but the
second one doesn't make any sense at all. It makes the motor rotate much
too slow when i calculate the number of machine cycles. I had to reduce the
double timing loop to a single loop, losing a lot of accuracy in the
rotation speed.

I hope someone can help me, because making a single timing loop doesn't
make any sense when counting the machine cycles ? I've added the small
program so you can have a look...

TIA,
Rob.


part 2 8523 bytes content-type:text/plain; charset="us-ascii"
;****************************************************************
;*   dstepper.asm Stepper Motor Contoller       april 2001      *
;*   By Rob Sanders  spam_OUTsagittariusTakeThisOuTspamchello.nl      PE1JFZ          *
;*   Rev. B on a PIC16F84 oscillator XT, WDT on (DMS-Ehv)       *
;*   B A S I C   O P E R A T I O N  E X P L A N A T I O N       *
;*                     UNMODIFIED                               *
;****************************************************************
;
;
;
LIST            P=16F84 , C=75 , F=INHX8M       ; define processor that we use.
;
__CONFIG        H'ED'                           ; define XT osc, WDT on, Code protect on, PowerUpTimer on.
                                               ; this is standard for the PIC16F84.
;
;  ======= Usage of Port Bits === declarations ===================
;
                                               ;-->PortA
PortA0          equ     0                       ; Ra0
PortA1          equ     1                       ; Ra1
PortA2          equ     2                       ; Ra2
PortA3          equ     3                       ; Ra3
PortA4          equ     4                       ; Ra4
;
PortB0          equ     0                       ; Rb0
PortB1          equ     1                       ; Rb1
PortB2          equ     2                       ; Rb2
PortB3          equ     3                       ; Rb3
Motor1L         equ     4                       ; Rb4 motor coil 1 A.
Motor1R         equ     5                       ; Rb5 motor coil 1 A'.
Motor2L         equ     6                       ; Rb6 motor coil 2 B.
Motor2R         equ     7                       ; Rb7 motor coil 2 B'.
;
;
INCLUDE "c:\mplab\dstepper\p16f84.inc"   ; definition of standard PIC regs, like rtcc, porta,b, status, etc.
;
                                               ; -->Declaration of some variables in RAM:
wait1           equ     10h                     ; delay variable.
wait2           equ     11h                     ; delay variable.
wait3           equ     12h                     ; delay variable.
GreatwaitReg    equ     13h                     ; long wait counter.
;
;
;**************************************************************************
;*                       Start Main Programm                              *
;**************************************************************************
;
               org     0000h                   ; in case of PIC16F84...
               goto    InitMicrochip           ; ...start main programm at address 0100h!
               org     0100h                   ; here is where the main programm starts.
                                               ;
InitMicrochip   call    InitPortsAndWdt         ; initialize ports and other important stuff.
               call    InitMotor               ; all outputs low

               movlw   .100                    ; give the user some time before startup
               call    waitXX100msec           ; wait 100x0.1sec=10 sec.

CW              bsf     portb,Motor1R           ; half-stepped rotation clockwise
               call    waitstapmsec            ; if you connected the wires in
               bcf     portb,Motor2L           ; the right way :-)
               call    waitstapmsec
               bsf     portb,Motor2R
               call    waitstapmsec
               bcf     portb,Motor1R
               call    waitstapmsec
               bsf     portb,Motor1L
               call    waitstapmsec
               bcf     portb,Motor2R
               call    waitstapmsec
               bsf     portb,Motor2L
               call    waitstapmsec
               bcf     portb,Motor1L
               call    waitstapmsec
               goto    CW
;
;*********************************
;*   End of main programm        *
;*********************************
;
;========Routines========Routines========Routines========Routines========Routines========
;Routines========Routines========Routines========Routines========Routines========Routines
                                               ;
                                               ;
               org     0010h                   ; routines start at 0010h!
;
;================================================================
;= Init Reg's + Watchdog + ports.                               =
;================================================================
InitPortsAndWdt clrf    status                  ; make all status flags default.
               clrf    tmr0                    ; before we jiggle with the WDT, clear the timer!
               bsf     status,rp0              ; select RAM register bank 1.

               clrf    intcon                  ; disable interrupts

                                               ; -->Define opion bits:
               movlw   B'00001111'             ; prescaler to WDT, WDT timeout approx 2.3sec.
               movwf   optreg                  ; store in the option register.

                                               ; -->Define pins for in & ouputs:
               clrf    porta                   ; clear port a
               movlw   B'00011111'             ; 1 = input pins,
                                               ; 0 = output pins
               tris    porta                   ; config port a as indicated

               clrf    portb                   ; clear port b
               movlw   B'00001111'             ;
               tris    portb                   ; config port b as indicated

               bcf     status,rp0              ; back to RAM register bank 0.

               retlw   0
;
;================================================================
;= waitXX100msec -> long time delay routine (with clrwdt!)      =
;================================================================
waitXX100msec   movwf   GreatwaitReg            ; store the waiting time!
xxwaitloop      call    wait100msec             ; use wait100msec as standard delay time
               decfsz  GreatwaitReg            ; all waitRounds done?
               goto    xxwaitloop              ; loop until finished.
               retlw   0
;
;
;================================================================
;= waitXXXmsec --> delay routines. (with clrwdt!)               =
;================================================================

;-->100msec Entry:
;
wait100msec     movlw   .216                    ; wait approx 33.3 msec
               call    wait
               movlw   .216                    ; wait another 33.3 msecs
               call    wait
               movlw   .216                    ; wait another 33.3 msecs
               call    wait
               retlw   0
;
;--> universal wait routine
;
wait            movwf   wait2                   ; load the waittime into wait2
               clrwdt                          ; reset the watchdogtimer
waitloop        decfsz  wait1                   ; 1 cycle
               goto    waitloop                ; 2 cycles
               decfsz  wait2                   ; 1 cycle
               goto    waitloop                ; 2 cycles
               retlw   0
;
;=================================================================
;
;--> timing calculations & stuff like that
;
; use 20 MHz XTAL for the following delays ((3x256) x N + 3xN) x 4 / F_XTAL)
;
; N=  DELAY=
; 0   0.0000  msec
; 1   0.1542  msec
; 2   0.3084  msec
; 3   0.4626  msec
; 216 33.307  msec
;
; Should be :
; 1 cycle = 200ns @ 20 MHz
; Wanted freq = 24*8*12.5 = 2400 Hz ===> 0.41666 msec
; This compares to 2083 clock cycles
; for N=2 there are 2083-(6*256)+(2*3) = 541 clock cycles left
; 541/3 = 180 clock cycles left over for
; Tweaking = (M*3) machine cycles = 180
;
; But found : 81 ( x 3 Mcycles) single loop ?????
;
;=================================================================
;
;======================
;= steptime for motor =
;======================
;
waitstapmsec    clrwdt                          ; clearwatchdogreg, we're still running...
               movlw   .81
               movwf   wait3
tweaking        decfsz  wait3                   ; 1 cycle
               goto    tweaking                ; 2 cycles
               retlw   0
;
;======================
;= init motor stuff   =
;======================
InitMotor       bcf     portb,Motor1L
               bcf     portb,Motor1R
               bcf     portb,Motor2L
               bcf     portb,Motor2R
               retlw   0
;
end


part 3 404 bytes content-type:text/plain; charset="iso-8859-1"
(decoded quoted-printable)



Rob Sanders
 2001\04\04@050937 by Roman Black
flavicon
face
Rob S wrote:

> I've been looking for two days at this strange problem now that I
> encountered while making a little program to to rotate a stepper-motor.
>
> The problem is that there are two timing loops in the program. The first
> one determines the start-up delay, and the second one determines the
> rotation speed. The first one does exactly what i calculated, but the
> second one doesn't make any sense at all. It makes the motor rotate much
> too slow when i calculate the number of machine cycles. I had to reduce the
> double timing loop to a single loop, losing a lot of accuracy in the
> rotation speed.
>
> I hope someone can help me, because making a single timing loop doesn't
> make any sense when counting the machine cycles ? I've added the small
> program so you can have a look...


Hi Rob, i'm surprised no-one has helped you as your
code is well commented and fairly easy to understand.

I see a couple of potential downfalls, your wait functions
use a lot of calls/returns, which chew up time, and
also may be pushing stack limits that can cause unpredictable
results.

I suggest a simpler more conventional wait function
something like this:
(i've modded your code)


;================================================================
;= waitXX100msec -> long time delay routine (with clrwdt!)      =
;================================================================
waitXX100msec   movwf   GreatwaitReg            ; store the waiting
time! (msb)

               clrf    count_inner             ; prepare lsb

loop_inner      decfsz  count_inner             ; dec and loop 256 times
               goto    loop_inner              ; 1+2 inst x 256 (delay period)

loop_outer      clrwdt                          ; give the dog a bone
               decfsz  GreatwaitReg            ; dec outer loop counter
               goto    loop_outer              ; 1+1+2 inst x value of Greatwaitreg
                                                ; (delay period)

               retlw   0                       ; return
;================================================================


You will find this easier to calc total delay time as you
vary motor speed and it doesn't use any more stack
levels, and the obvious size/simplicity savings.

You can add a third (or fourth) loop with no effort, and
for varying timings you can always load the inner loop
vars with a value instead of clearing them (which=256).

My personal pref with stepper motors is to set the inner
loop value so that when Greatvalue==256 I get the slowest
speed I need. You then get the best speed range possible
just by varying the Greatvalue byte.
:o)
-Roman

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\04@060741 by Rob S

flavicon
face
Hi Roman,

>Hi Rob, i'm surprised no-one has helped you as your
>code is well commented and fairly easy to understand.

Thank you ;-)

>I see a couple of potential downfalls, your wait functions
>use a lot of calls/returns, which chew up time, and
>also may be pushing stack limits that can cause unpredictable
>results.

Yes, that's possible. As far as I know a PIC16F84 can handle subroutines up
to 8 levels deep, before stack problems are bound to occure. I'll try to
re-write the (allready fairly simple) program to see if this helps.
>
>I suggest a simpler more conventional wait function
>something like this:
>(i've modded your code)
>
>
>;================================================================
>;= waitXX100msec -> long time delay routine (with clrwdt!)      =
>;================================================================
<CUT>

You've modded the part of the code that was working right :-D

>My personal pref with stepper motors is to set the inner
>loop value so that when Greatvalue==256 I get the slowest
>speed I need. You then get the best speed range possible
>just by varying the Greatvalue byte.

Yes, the longer the wait, the slower the rotation speed.
I'll try to re-write the program now, with fewer sub's.

regards,
Rob.

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\04@062236 by Michael Rigby-Jones

flavicon
face
{Quote hidden}

I had a quick look at the source, and I am still not sure how quickly you
want to rotate the stepper motor.  The figure 2400Hz is mentioned in the
code; does this mean you want to rotate at 2400 RPM or you want 2400 half
steps per second?  How many steps are required per revolution?

Regards

Mike

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\04@081634 by Drew Vassallo

picon face
{Quote hidden}

I guess I must be missing something here with this "long delay," but isn't
this just 3*256 cycles + 4*GreatwaitReg??  There are no "inner" and "outer"
loops.  The max this could be is 1792 cycles.  I don't know what speed
you're running, but that's not 100s of ms.  Maybe this is exactly what you
want, but I'm missing why you're calling these delay registers "MSB" and
"LSB" when they're not.

--Andrew
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\04@090336 by Rob S

flavicon
face
>I had a quick look at the source, and I am still not sure how quickly you
>want to rotate the stepper motor.  The figure 2400Hz is mentioned in the
>code; does this mean you want to rotate at 2400 RPM or you want 2400 half
>steps per second?  How many steps are required per revolution?
>Regards
>Mike

Hi Mike,

The motor should be rotated at 12.5 rps.
With a 24 step/revolution motor and 8 phase half stepping mode this results
in 2400 Hz or 0.41666 ms time between the changes in phase. (24 times 8
times 12.5)

regards,
Rob

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\04@091832 by Rob S

flavicon
face
I found the problem in my motordriver, finally ! After reading Mike's mail
I realised that
it wasn't the software that's misbehaving, but my way of measuring...

If the change between the phases occures every 0.41666 ms then, if measured
on only 1 output, the frequency won't read 2400 Hz but 2400 / 8 = 300 Hz.
Which is pretty close to what I saw during my first attempts with de double
loop...

Thank you all for helping me find out !
regards,
Rob


Rob Sanders
===========

Sagittarius meteoren waarneem groep (DMS)
*Homepage: members.chello.nl/~r.sanders3/stars/meteors/
*E-Mail  : EraseMEsagittariusspam_OUTspamTakeThisOuTchello.nl
*Snail M : Prunellapad 17, ZIP NL5643BW17
*City    : Eindhoven, The Netherlands
*Coord.  : Obs : 5° 31' 44" E ; 51° 21' 58" N (ANWB paddestoel 20934 / 21510)
*GSM-BEN : 06.24.84.90.77

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\04@092244 by Clive Frederickson

flavicon
face
Hi Rob

1st bit:

The short delay routine waitstapmsec delay time can be calculated by

Pcy delay = (n-1) * 3 + 9               Where n is the loop counter. This
includes the 2pcy from the call instruction.

;======================
;= steptime for motor =
;======================
;
;
Arrives here 2 pcy from Call
waitstapmsec
       clrwdt                          ; clearwatchdogreg, we're still
running...      1 pcy
       movlw   .81
1 pcy
               movwf   wait3
1 pcy
tweaking  decfsz  wait3                   ; 1 cycle
1 pcy if not zero, 2 pcy if zero
               goto    tweaking                ; 2 cycles
2 pcy if not zero, 0 skipped if zero
               retlw   0
2 pcy Return to Call

So the DECFSZ loop will take 3 instructions per count (N) except for the
last one which will take 2 pcy.

So for n=81

Pcy     = (81-1)*3+9
       = 80 * 3 +9
       = 240 +9
       = 249 pcy delay or 249 * 200ns =

The max delay for this routine would be N=0 (256 counts)

Pcy = (256-1)*3+9       =  255 * 3+9    = 765+9 = 774   or 200ns * 774 =
154.8us

Next
First thing to mention is you do not clear the wait 1 reg. Although in
theory this should be zero. From first power up that is not guaranteed.

Wait
2 pcy from Call
       movwf   wait2                  ; load the waittime into wait2
1 pcy
               clrwdt                                  ; reset the
watchdogtimer                           1 pcy
waitloop   decfsz  wait1                   ; 1 cycle
1 pcy <>0,      2 pcy =0
               goto    waitloop                ; 2 cycles
2 pcy <>0,      0 pcy = 0
               decfsz  wait2                   ; 1 cycle
1 pcy <>0       2 pcy =0
               goto    waitloop                ; 2 cycles
2 pcy <>0       0 pcy =0
               retlw   0
2 pcy return to call

So      the inner loop will be  pcy = (n-1)*3+2         3 pcy per count - 1
plus 2 pcy when count = zero.
                                               = (256-1)*3+2
                                               = 765 +2
                                               = 767 PCY

The outer loop will be pcy = ((m -1)*(767+3) +(767+2))+6

                                               m-1     = number of complete
loops for outloop.
                                               767+3   = Number of pcy per
complete loop for outer loop
                                               767+2   = Number of pcy for
the last pass of the loop
                                               +6              = pcy for
the call, set up and return.

Or in short     pcy = (m-1)*770 +775

So for a count of 10, you will get 7705 pcy's delay. Or 7705 * 200ns =
1.541ms

To work m from the pcy;

       M       = 1 + (pcy - 775)/770

               = 1 + (7705 -775)/770   =1+ ( 6930 / 770)       = 1 + 9 = 10


The one addition to your loop would be to add CLRF wait1 as the first
instruction after the wait label.


I hope this helps. It can be a bit confusing though. So just copy the loops
into a new .asm file and simulate them with MPLAB. The play with some
different values.



Regards

Clive Frederickson
R&D Technician (CECF Group)

       ----------
       From:  Rob S [SMTP:sagittariusspamspam_OUTCHELLO.NL]
       Sent:  03 April 2001 13:52
       Subject:  [PIC]: pic changing program speed ?

       Hi,

       I've been looking for two days at this strange problem now that I
       encountered while making a little program to to rotate a
stepper-motor.

       The problem is that there are two timing loops in the program. The
first
       one determines the start-up delay, and the second one determines the
       rotation speed. The first one does exactly what i calculated, but
the
       second one doesn't make any sense at all. It makes the motor rotate
much
       too slow when i calculate the number of machine cycles. I had to
reduce the
       double timing loop to a single loop, losing a lot of accuracy in the
       rotation speed.

       I hope someone can help me, because making a single timing loop
doesn't
       make any sense when counting the machine cycles ? I've added the
small
       program so you can have a look...

       TIA,
       Rob.


*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Dyson's Contrarotator(TM) is the first washing machine with 2
drums rotating in opposite directions at once. This means it
gives the cleanest wash results in the fastest time and takes
the largest loads. The Contrarotator(TM) is now on sale at
selected retailers, and will be available nationwide in spring 2001.

For more information,
please visit our website at http://www.dyson.com.
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\04@112155 by David Cary

flavicon
face
I believe that
Roman Black <@spam@fastvidKILLspamspamEZY.NET.AU> on 2001-04-04 04:06:30 AM
meant to write something like this:

;================================================================
;= waitXX100msec -> long time delay routine (with clrwdt!)      =
;================================================================
waitXX100msec   movwf   GreatwaitReg            ; store the waiting
time! (msb)

loop_outer:
               clrf    count_inner             ; prepare lsb

loop_inner:
               decfsz  count_inner             ; dec and loop 256 times
               goto    loop_inner              ; 1+2 inst x 256 (delay period)

               clrwdt                          ; give the dog a bone
               decfsz  GreatwaitReg            ; dec outer loop counter
               goto    loop_outer              ; 1+1+2 inst x value of
Greatwaitreg
                                                ; (delay period)

               retlw   0                       ; return
;================================================================
; You can add a third (or fourth) loop with no effort, and
; for varying timings you can always load the inner loop
; vars with a value instead of clearing them (which=256).
;
; My personal pref with stepper motors is to set the inner
; loop value so that when Greatvalue==256 I get the slowest
; speed I need. You then get the best speed range possible
; just by varying the Greatvalue byte.
; -- Roman Black

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\04@113711 by Roman Black

flavicon
face
Drew Vassallo wrote:
{Quote hidden}

Actually, there is a typo, the 2nd goto loop_outer
should be goto loop_inner. Sorry! :o)
-Roman

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


More... (looser matching)
- Last day of these posts
- In 2001 , 2002 only
- Today
- New search...