using interrupt mode : help please

jyb

Senior Member
for a special need for speed i wrote a code loop as shorter as possible ,the probleme is how to exit from this loop ? i would use the interrupt mode which works correctly just first time , others time no more works. i presume
a misuse of interrupt command
on other part in the interrupt cell code i put a "setint off" because when exiting "motor loop" i must cancel the return from interrupt ,to permit a return to main program and not back where interrupt occurs on the loop
above here is a part of my code . i can't add anything on the motor1 loop code
main:
gosub switchestest
goto motor

motor:
setint %11111101,%11111101,D 'start interrup watching
motor1:
readadc10 canaladc , potentiometre 'read value to potar1
pulsout pulsadr , delai pauseus potentiometre'send pulse to motor
goto moteur1 'loop to motor1
interrupt:
setint off
goto main
 

hippy

Ex-Staff (retired)
It's the "goto main" which is the problem; this disables further interrupts. You need to use a RETURN. In the the interrupt you can set a flag which tells the outer loop to terminate ...

Code:
main:
  ...
  b0 = 0
  SetInt ...
motor1:
  Readadc ...
  PulsOut ...
  If b0 = 0 Then motor1
  Goto main

Interrupt:
  b0 = 1
  Return
 

jyb

Senior Member
just what i would avoid

It's the "goto main" which is the problem; this disables further interrupts. You need to use a RETURN. In the the interrupt you can set a flag which tells the outer loop to terminate ...

Code:
main:
  ...
  b0 = 0
  SetInt ...
motor1:
  Readadc ...
  PulsOut ...
  If b0 = 0 Then motor1
  Goto main

Interrupt:
  b0 = 1
  Return
add testing command onto the loop
is just what i would avoid because i need a very fast loop
if i understand it is not possible to put a "setint off" in the interrupt routine
to cut off the current interrupt treatment and later restart another
setint xxxx,xxxx,D i am sad:(
 

hippy

Ex-Staff (retired)
You can put a SETINT OFF within the interrupt to disable further interrupts, but what you cannot do is a GOTO Main and then have interrupts re-enabled; for interrupts to work as intended the interrupt routine must end with a RETURN.

This does then mean that you need to check if the interrupt has occurred in the outer loop, and this will slow the loop time down. This is just a fact of life in using a PICAXE.

In most cases this is not a problem and there may be ways to mitigate when it is; the PICAXE can be run at its fastest speed and if you are generating a pulse proportional to the speed of the motor controlled you could perhaps use PWMOUT and vary the duty. At fastest speeds the additional checks for an interrupt having occurred should only add a hundred or so microseconds to the loop time.

I don't recall that you have fully explained why the loop is as it is, why it needs to be so fast, or what speeds you actually require. Perhaps a full explanation of what you are doing and timing required will help find alternative or workable solutions.
 

westaust55

Moderator
You do not need a SETINT OFF command within the Interrupt: subroutine.

The firmware automatically and permanently disables the SETINT function when the Interrupt

From the PICAXE Manual 2 (under the second page of the SETINT command information):
Notes:
1) Every program which uses the SETINT command must have a corresponding
interrupt: sub-procedure (terminated with a return command) at the bottom of the program.
2) When the interrupt occurs, the interrupt is permanently disabled. Therefore to re-enable the interrupt (if desired) a SETINT command must be used within the interrupt: sub-procedure itself. The interrupt will not be enabled until the ‘return’ command is executed.
 

hippy

Ex-Staff (retired)
2) When the interrupt occurs, the interrupt is permanently disabled. Therefore to re-enable the interrupt (if desired) a SETINT command must be used within the interrupt: sub-procedure itself. The interrupt will not be enabled until the ‘return’ command is executed.
That wording is perhaps not the best and I've made a note of it.

When an interrupt occurs, the interrupt routine is entered and subsequent interrupts are disabled until -

1) a SETINT is issued and a RETURN terminates the interrupt routine

2) a RETURN terminates the interrupt routine and a subsequent SETINT is issued.

3) The program is restarted by power-cycling, a Hard Reset or issuing the RESET command and, in all cases, until a SETINT is issued.
 

jyb

Senior Member
pwmout was my first approach

You can put a SETINT OFF within the interrupt to disable further interrupts, but what you cannot do is a GOTO Main and then have interrupts re-enabled; for interrupts to work as intended the interrupt routine must end with a RETURN.

This does then mean that you need to check if the interrupt has occurred in the outer loop, and this will slow the loop time down. This is just a fact of life in using a PICAXE.

In most cases this is not a problem and there may be ways to mitigate when it is; the PICAXE can be run at its fastest speed and if you are generating a pulse proportional to the speed of the motor controlled you could perhaps use PWMOUT and vary the duty. At fastest speeds the additional checks for an interrupt having occurred should only add a hundred or so microseconds to the loop time.

I don't recall that you have fully explained why the loop is as it is, why it needs to be so fast, or what speeds you actually require. Perhaps a full explanation of what you are doing and timing required will help find alternative or workable solutions.
i want to drive a big stepper motor . For its power switching it is drived by a "leadshine"box which need a varying frequency signal and a direction signal. My first approach was using pwmout/pwmduty but it does not fit the need of varying frequency. using just only pwmout to change frequency cause motor jerking because synchronization lose.the only other way i found is the loop as shorter as possible ,using interrupt when stopping stepper rotation.if i can't reach the target in this way i believe i have to look to the assembler side........
 

hippy

Ex-Staff (retired)
I've no idea what a "leadshine" box may be but what frequencies you need to generate is probably crux to the problem.

The fastest loop time you can get with an interrupted flag check is around 175us with a 28X2 at 64MHz, which is around 5.7kHz, without the flag check it's around 150us or 6.7kHz.

What frequencies are you aiming for ?
 

jyb

Senior Member
measured with my old scope tektronix

I've no idea what a "leadshine" box may be but what frequencies you need to generate is probably crux to the problem.

The fastest loop time you can get with an interrupted flag check is around 175us with a 28X2 at 64MHz, which is around 5.7kHz, without the flag check it's around 150us or 6.7kHz.

What frequencies are you aiming for ?
i use a picaxe 40x2 pic18f45k22running at 64mhz
for 900rpm motor need theoreticaly900rpm x 400step=360000 pulses/second
fastest loop
speed reached ,measured with a digital tachometer is 890/901 rpm max(this fit me)
time between each pulse measured with a scope tektronix 2225 100mhz
is approximatively 0,16mS
this loop run correctly ,start and stop motor by turning potentiometer is ok
only missing feature is urgency halt

the shortest do while loop i tried gives 660 rpm max on digital tachometer and don't fit to my project

leadshine box(chinese) is a special driver for big stepper motors which gives 8 amps/on four phasis. it need a frequency pulses signal an a dir level signal
thanks for the time you gave me
:)
 

hippy

Ex-Staff (retired)
It does seem you are just within the bounds of possibilities with the PICAXE, adding interrupt checking, beyond it. The question then may be how to handle things once the interrupt has been triggered.

Setting a flag and checking that is too slow. Baling out of interrupt with GOTO doesn't work, but what about RESET which will restart the program, allow interrupts to be enabled ?

Code:
  Gosub switchestest
  SetInt ...
  Do
    ReadAdc10 ...
    PulsOut ...
  Loop

Interrupt:
  Reset
It perhaps depends on what you need to do when interrupted.
 
Top