PDA

View Full Version : Hot to handle multiple interrupt sources?



elcrcp
- 21st April 2013, 04:17
Hi guys, I'm working on a project and using PIC16F877A. I need to use multiple interrupts sources as TMR0, TMR1, RB0 etc. but i don't know how to proccess them in different interrupt routines. Is there any way to direct them to releated interrupt routine other than polling their interrupt flags?
I mean, I know following codes won't work but is there a way to use interrupts like following codes,


ON TMR0 INTERRUPT GOTO tmr0_int
ON TMR1 INTERRUPT GOTO tmr1_int
ON RB0 INTERRUPT GOTO rb0_int

Or do I must use polling methode like following


ON INTERRUPT GOTO INTCHCK
....
....
INTCHCK:
IF INTCON.2=1 THEN
GOTO tmr0_int
ENDIF
IF PIR.0=1 THEN
GOTO tmr1_int
ENDIF
IF INTCON.0=1 THEN
GOTO rb0_int
ENDIF

PS: I would not prefer polling methode since it will lose time while checking flags, it would be great if there is a way to run releated interrupt subroutine directly like some other microcontroller models

Demon
- 21st April 2013, 04:35
Have you checked this out?
http://DarrelTaylor.com/DT_INTS-18/home.html

Search DT-INT by Darrel on the forums.

Robert

elcrcp
- 21st April 2013, 06:37
I haven't seen that, it may help me a lot, thanks.

HenrikOlsson
- 21st April 2013, 07:58
Hi,
DT-INTS is probably the best way to go but to answer the original question you do need to poll the individual interrupt request flags, there simply is no way around that because there is only one interrupt vector in the PIC12/16/18 (not counting high/low priority). Some microcontrollers have, like you say, an interrupt vector for each interrups source but these PICs doesn't so the only way to determine the cause of the interrupt is to poll the flags. If you're going with DT-Ints it does that for you though.

/Henrik.

Charlie
- 21st April 2013, 10:44
I think that for the PIC16f877A you will need DT_INTS-14 version, not the DT_INTS-18 (which is only for the 18 series devices, I believe). Both versions, and a few other useful things, can be found here: http://dt.cambs.net/
Perhaps these things should find their way into the WIKI?
It's always a hunting trip to find and figure out the latest versions, but worth the effort when you eventually get there.

elcrcp
- 21st April 2013, 23:11
Thanks for answers, I didn't know PIC doesn't have different interrupt vectors, I thought it has. I tried DT-INTS on my codes with only 1 source interrupt. It kinda worked but not as it has to be.. It's working as it has to when I don't use DT-INTS but it's working in an unexpected way when I use DT-INTS. I don't know why...

Demon
- 21st April 2013, 23:14
Post your complete code.

elcrcp
- 21st April 2013, 23:33
Ok, I'm explaining what I'm trying to do, my codes are little bit long.
I'm controlling 6 motors seperately and applying them PWM signals by using TMR0, I'm getting encoder data back and counting them to control positions of motors.
Here is my first code without DT-INTS, I'm compiling them with PBP247, I want to count 50 pulses from each to get them correct position and make them spin for 1 quarter round, and it's working as it has to be.


'Defining controller properties
@ DEVICE PIC16F877A
@ DEVICE PIC16F877A,HS_OSC
@ DEVICE PIC16F877A,WDT_OFF
@ DEVICE PIC16F877A,LVP_OFF
DEFINE OSC 16
on interrupt goto kesme
OPTION_REG=%10000100
INTCON=%10100000
ADCON1=7
'Defining Port usages and clearing ports for start
TRISA=%00000000
TRISB=%00000000
TRISC=%11110000
TRISD=%00000011
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

'DEFINE ENCODER INPUTS
SYMBOL EN1=PORTC.7
SYMBOL EN2=PORTC.6
SYMBOL EN3=PORTC.5
SYMBOL EN4=PORTC.4
SYMBOL EN5=PORTD.1
SYMBOL EN6=PORTD.0
'DEFINE MOTOR CONTROL OUTPUTS
SYMBOL M1A=PORTB.7
SYMBOL M1B=PORTB.6
SYMBOL M2A=PORTB.5
SYMBOL M2B=PORTB.4
SYMBOL M3A=PORTB.3
SYMBOL M3B=PORTB.2
SYMBOL M4A=PORTD.7
SYMBOL M4B=PORTD.6
SYMBOL M5A=PORTD.5
SYMBOL M5B=PORTD.4
SYMBOL M6A=PORTD.3
SYMBOL M6B=PORTD.2
'DEFINE VARIABLES
EN1PRE var BIT
EN1NOW var BIT
EN2PRE var BIT
EN2NOW var BIT
EN3PRE var BIT
EN3NOW var BIT
EN4PRE var BIT
EN4NOW var BIT
EN5PRE var BIT
EN5NOW var BIT
EN6PRE var BIT
EN6NOW var BIT
M1STEPSIZE VAR BYTE
M2STEPSIZE VAR BYTE
M3STEPSIZE VAR BYTE
M4STEPSIZE VAR BYTE
M5STEPSIZE VAR BYTE
M6STEPSIZE VAR BYTE
M1STATE VAR BYTE
M2STATE VAR BYTE
M3STATE VAR BYTE
M4STATE VAR BYTE
M5STATE VAR BYTE
M6STATE VAR BYTE
STANDC VAR BYTE
M1C var BIT
M2C var BIT
M3C var BIT
M4C var BIT
M5C var BIT
M6C var BIT
walk_mode var byte
duty_check var BIT
duty_ctrl var BIT
duty1 var byte
duty0 var byte
M1POWER var BIT
M2POWER var BIT
M3POWER var BIT
M4POWER var BIT
M5POWER var BIT
M6POWER var BIT
STANDUP_COUNT VAR BYTE
RST:

CLEAR 'Clear all variables
'Defining starting values of some variables
M1STEPSIZE=50
M2STEPSIZE=50
M3STEPSIZE=50
M4STEPSIZE=50
M5STEPSIZE=50
M6STEPSIZE=50
EN1PRE=EN1
EN2PRE=EN2
EN3PRE=EN3
EN4PRE=EN4
EN5PRE=EN5
EN6PRE=EN6
M1POWER=1
M2POWER=1
M3POWER=1
M4POWER=1
M5POWER=1
M6POWER=1
STANDUP_COUNT=50

pause 3000
walk_mode=0 'walk_mode defines which movement mode RHEX will use
TMR0=255 'Start Timer so interrupts and movement will start

'RHEX IS STANDING UP
'Check every motor encoder value and stop releated motor if it reached to
'defined position
'MXC is used for motor running control, if a motor is reached to desired
'position and stopped, do not check and lose time on it
STANDUP:
GOSUB ENCOUNTER
IF M1C=0 THEN
IF M1STATE>=STANDUP_COUNT THEN
M1POWER=0
M1C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M2C=0 THEN
IF M2STATE>=STANDUP_COUNT THEN
M2POWER=0
M2C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M3C=0 THEN
IF M3STATE>=STANDUP_COUNT THEN
M3POWER=0
M3C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M4C=0 THEN
IF M4STATE>=STANDUP_COUNT THEN
M4POWER=0
M4C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M5C=0 THEN
IF M5STATE>=STANDUP_COUNT THEN
M5POWER=0
M5C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M6C=0 THEN
IF M6STATE>=STANDUP_COUNT THEN
M6POWER=0
M6C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF STANDC>=6 THEN
M1STATE=0
M2STATE=0
M3STATE=0
M4STATE=0
M5STATE=0
M6STATE=0
STANDC=0
PAUSE 3000
GOTO RST
ELSE
GOTO STANDUP
ENDIF
GOTO RST

'COUNTING PULSES FROM ENCODER OUTPUTS
'Read values of encoders and if they are different from previous value
'then it means, a transition is occured, so a pulse is given
'increase the releated encoder count
'Note: This will cause 2 counts for every pulse, not 1 count for 1 pulse.
ENCOUNTER:
EN1NOW=EN1
EN2NOW=EN2
EN3NOW=EN3
EN4NOW=EN4
EN5NOW=EN5
EN6NOW=EN6
IF EN1NOW!=EN1PRE THEN
M1STATE=M1STATE+1
ENDIF
EN1PRE=EN1NOW
IF EN2NOW!=EN2PRE THEN
M2STATE=M2STATE+1
ENDIF
EN2PRE=EN2NOW
IF EN3NOW!=EN3PRE THEN
M3STATE=M3STATE+1
ENDIF
EN3PRE=EN3NOW
IF EN4NOW!=EN4PRE THEN
M4STATE=M4STATE+1
ENDIF
EN4PRE=EN4NOW
IF EN5NOW!=EN5PRE THEN
M5STATE=M5STATE+1
ENDIF
EN5PRE=EN5NOW
IF EN6NOW!=EN6PRE THEN
M6STATE=M6STATE+1
ENDIF
EN6PRE=EN6NOW
RETURN
'TMR0 INTERRUPT ROUTINE
'All motor movements are provided by this interrupt routine
'A PWM signal is created by using TMR0 timer and applied to
'motors, all PWM signals will be created by TMR0 for all movement types
disable
kesme:
if walk_mode=0 then
duty1=128
duty0=(256-duty1)
if duty_check=0 then
duty_ctrl=1
M1A=M1POWER
M1B=0
M2A=0
M2B=M2POWER
M3A=M3POWER
M3B=0
M4A=0
M4B=M4POWER
M5A=M5POWER
M5B=0
M6A=0
M6B=M6POWER
TMR0=duty1
endif
if duty_check=1 then
duty_ctrl=0
M1A=0
M1B=0
M2A=0
M2B=0
M3A=0
M3B=0
M4A=0
M4B=0
M5A=0
M5B=0
M6A=0
M6B=0
TMR0=duty0
endif
endif
if duty_ctrl=1 then
duty_check=1
else
duty_check=0
endif
INTCON.2=0
resume
enable
end

And this is the version of same code I used DT-INTS, although I changed and count for only 20 pulses from encoders, motors are spininning 4 rounds when they need to spin for only a quarter round


DEFINE OSC 16

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 TMR0_INT, _kesme, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

OPTION_REG=%10000100
@ INT_ENABLE TMR0_INT ; enable Timer 0 interrupts

ADCON1=7
'Defining Port usages and clearing ports for start
TRISA=%00000000
TRISB=%00000000
TRISC=%11110000
TRISD=%00000011
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

'DEFINE ENCODER INPUTS
SYMBOL EN1=PORTC.7
SYMBOL EN2=PORTC.6
SYMBOL EN3=PORTC.5
SYMBOL EN4=PORTC.4
SYMBOL EN5=PORTD.1
SYMBOL EN6=PORTD.0
'DEFINE MOTOR CONTROL OUTPUTS
SYMBOL M1A=PORTB.7
SYMBOL M1B=PORTB.6
SYMBOL M2A=PORTB.5
SYMBOL M2B=PORTB.4
SYMBOL M3A=PORTB.3
SYMBOL M3B=PORTB.2
SYMBOL M4A=PORTD.7
SYMBOL M4B=PORTD.6
SYMBOL M5A=PORTD.5
SYMBOL M5B=PORTD.4
SYMBOL M6A=PORTD.3
SYMBOL M6B=PORTD.2
'DEFINE VARIABLES
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3

EN1PRE var BIT
EN1NOW var BIT
EN2PRE var BIT
EN2NOW var BIT
EN3PRE var BIT
EN3NOW var BIT
EN4PRE var BIT
EN4NOW var BIT
EN5PRE var BIT
EN5NOW var BIT
EN6PRE var BIT
EN6NOW var BIT
M1STEPSIZE VAR BYTE
M2STEPSIZE VAR BYTE
M3STEPSIZE VAR BYTE
M4STEPSIZE VAR BYTE
M5STEPSIZE VAR BYTE
M6STEPSIZE VAR BYTE
M1STATE VAR BYTE
M2STATE VAR BYTE
M3STATE VAR BYTE
M4STATE VAR BYTE
M5STATE VAR BYTE
M6STATE VAR BYTE
STANDC VAR BYTE
M1C var BIT
M2C var BIT
M3C var BIT
M4C var BIT
M5C var BIT
M6C var BIT
walk_mode var byte
duty_check var BIT
duty_ctrl var BIT
duty1 var byte
duty0 var byte
M1POWER var BIT
M2POWER var BIT
M3POWER var BIT
M4POWER var BIT
M5POWER var BIT
M6POWER var BIT
STANDUP_COUNT VAR BYTE
RST:

CLEAR 'Clear all variables
'Defining starting values of some variables
M1STEPSIZE=50
M2STEPSIZE=50
M3STEPSIZE=50
M4STEPSIZE=50
M5STEPSIZE=50
M6STEPSIZE=50
EN1PRE=EN1
EN2PRE=EN2
EN3PRE=EN3
EN4PRE=EN4
EN5PRE=EN5
EN6PRE=EN6
M1POWER=0
M2POWER=0
M3POWER=0
M4POWER=0
M5POWER=0
M6POWER=0
STANDUP_COUNT=20

pause 3000
walk_mode=0 'walk_mode defines which movement mode RHEX will use
TMR0=255 'Start Timer so interrupts and movement will start

'RHEX IS STANDING UP
'Check every motor encoder value and stop releated motor if it reached to
'defined position
'MXC is used for motor running control, if a motor is reached to desired
'position and stopped, do not check and lose time on it
STANDUP:
GOSUB ENCOUNTER
IF M1C=0 THEN
IF M1STATE>=STANDUP_COUNT THEN
M1POWER=1
M1C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M2C=0 THEN
IF M2STATE>=STANDUP_COUNT THEN
M2POWER=1
M2C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M3C=0 THEN
IF M3STATE>=STANDUP_COUNT THEN
M3POWER=1
M3C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M4C=0 THEN
IF M4STATE>=STANDUP_COUNT THEN
M4POWER=1
M4C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M5C=0 THEN
IF M5STATE>=STANDUP_COUNT THEN
M5POWER=1
M5C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M6C=0 THEN
IF M6STATE>=STANDUP_COUNT THEN
M6POWER=1
M6C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF STANDC>=6 THEN
M1STATE=0
M2STATE=0
M3STATE=0
M4STATE=0
M5STATE=0
M6STATE=0
STANDC=0
PAUSE 3000
GOTO RST
ELSE
GOTO STANDUP
ENDIF
GOTO RST

'COUNTING PULSES FROM ENCODER OUTPUTS
'Read values of encoders and if they are different from previous value
'then it means, a transition is occured, so a pulse is given
'increase the releated encoder count
'Note: This will cause 2 counts for every pulse, not 1 count for 1 pulse.
ENCOUNTER:
EN1NOW=EN1
EN2NOW=EN2
EN3NOW=EN3
EN4NOW=EN4
EN5NOW=EN5
EN6NOW=EN6
IF EN1NOW!=EN1PRE THEN
M1STATE=M1STATE+1
ENDIF
EN1PRE=EN1NOW
IF EN2NOW!=EN2PRE THEN
M2STATE=M2STATE+1
ENDIF
EN2PRE=EN2NOW
IF EN3NOW!=EN3PRE THEN
M3STATE=M3STATE+1
ENDIF
EN3PRE=EN3NOW
IF EN4NOW!=EN4PRE THEN
M4STATE=M4STATE+1
ENDIF
EN4PRE=EN4NOW
IF EN5NOW!=EN5PRE THEN
M5STATE=M5STATE+1
ENDIF
EN5PRE=EN5NOW
IF EN6NOW!=EN6PRE THEN
M6STATE=M6STATE+1
ENDIF
EN6PRE=EN6NOW
RETURN
'TMR0 INTERRUPT ROUTINE
'All motor movements are provided by this interrupt routine
'A PWM signal is created by using TMR0 timer and applied to
'motors, all PWM signals will be created by TMR0 for all movement types
kesme:
if walk_mode=0 then
duty1=150
duty0=(256-duty1)
if duty_check=0 then
duty_ctrl=1
M1A=1
M1B=M1POWER
M2A=M2POWER
M2B=1
M3A=1
M3B=M3POWER
M4A=M4POWER
M4B=1
M5A=1
M5B=M5POWER
M6A=M6POWER
M6B=1
TMR0=duty1
endif
if duty_check=1 then
duty_ctrl=0
M1A=0
M1B=0
M2A=0
M2B=0
M3A=0
M3B=0
M4A=0
M4B=0
M5A=0
M5B=0
M6A=0
M6B=0
TMR0=duty0
endif
endif
if duty_ctrl=1 then
duty_check=1
else
duty_check=0
endif
'INTCON.2=0
@ INT_RETURN
end

PS: Second code is compiling with MPASM as DT asks

mark_s
- 22nd April 2013, 00:27
Hello

Have you seen this for control of more than one RC servo.

http://www.darreltaylor.com/DT_INTS-14/SPWM.html

Another in the Wiki section.

http://www.picbasic.co.uk/forum/content.php?r=270-Driving-up-to-9-servos-with-2-I-O-lines

Edit.: Never mind I see from the code you are using servos with encoders

Demon
- 22nd April 2013, 01:40
I'd suggest getting one motor working first, keep your code as simple as possible as a start. Once that works, add a second motor and see if timing remains stable.

Figure out if issue is in timer interrupt, or having multiple motors.

Robert

Edit: Why GOSUB Encounter? It's only called once that I can see. Why not just plug in the subroutine at the GOSUB?

elcrcp
- 22nd April 2013, 02:24
main loop is STANDUP in this code, and program remains in that main loop until all motors get into position, ENCOUNTER subroutine is called every time loop starts, and I'm counting pulses from encoders with it. My encoders giving a pulse every 5ms at full speed and controller can complete that loop in microseconds, so controller can catch up any pulse and count it or thats what I thought =)
But I still have question marks in my mind, I didn't change the code in the end, just added DT-INTS and I belive I added them into code properly, but result is not right. I wonder if there are some tips or things about usage of DT-INTS

elcrcp
- 22nd April 2013, 03:13
These are problems I observed in my code with DT-INTS;
1- There is 3 seconds pause command after defining variables and before start motor controls but motors are starting to run directly when i plug the power cable.
2- Program cannot go out of STANDUP loop until all of encoders give 50 pulses but although I unplugged4 motors from system without changing the code, remaining 2 motors running , then pausing (not pausing from the start, it looks like it pauses after a jump) and running again and pausing ....
3- As far as I see, program is not giving a thing about main program and ENCOUNTER subroutine
4- Interrupt subroutine is working, because motors cannot run before int routine run but nothing else is running...

I just cant see what is the problem here, maybe I should give up on DT-INTS and use polling methode for multiple interrupts :frown:

Demon
- 22nd April 2013, 12:12
I think Timer starts at top with INT_ENABLE.

You have PAUSE 3 seconds at bottom of main loop (no idea why).

DT-INT is by far the easiest method to control interrupts, especially when you have more than one.

As I said, make a copy of your program and keep code for only 1 motor until you debug your logic. Then add 1 motor and see how that goes. Then all 6 only when logic is perfect.

Start small. Have you tried DT's beginner examples?

Edit: I don't see where you set T1CON.

Demon
- 22nd April 2013, 12:27
This is all you need to blink an LED.


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

T1CON = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

Main:
PAUSE 1
GOTO Main

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

elcrcp
- 22nd April 2013, 14:55
This was my trial code, I wrote it with only 1 interrupt source to try DT-INTS so I didn't use TMR1 or any other interrupt source in this code, if I can make this code work then i'll use other sources. I only used TMR0 and set it at the very beginning with "OPTION_REG=%10000100" then providing an interrupt with "TMR0=255"
Pauses are for observing the system, so I can observe rotation amount before it starts run again.
timer may be starting with INT_ENABLE as you said, I'll check it, and I'll apply a few more tests too. I'll report results here.
I didn't try DT beginner examples because I didn't need them but I think I should try them to understand it's logic better.

elcrcp
- 22nd April 2013, 16:05
---wrong alert---

elcrcp
- 22nd April 2013, 19:39
Ok now, something very funny and absurd has happened :confused: Before explaining everything, I want to thank again everybody for their help.
I started to test codes and tried to find where was the exact problem. First of all, yes Robert you were right TMR0 instantly starting to run after "@ INT_ENABLE TMR0_INT" I replaced it's location first and then while looking for problem, I figured out that program is running "STANDUP" and "ENCOUNTER" programs only once, then I stopped calling "ENCOUNTER" and I saw that "STANDUP" is working very fine. Then I added another subroutine to program for testing, just toggling a pin and called it instead of "ENCOUNTER" there was no problem, everything was perfect.
So, what was the problem with "ENCOUNTER" I comment all lines of "ENCOUNTER" and started to comment out line by line to see where is the problem exactly. While I commenting out lines, I compiled and tried the program on every line of "ENCOUNTER".

Well now is the funny part, at the end commenting out of lines, while I was thinking "damn I tried all lines and got no error, now its back to old code and wont work as it is" it worked without any problem.. I didnt change any letter of "ENCOUNTER" just commented them in and out thats all, but it worked... Now it counts pulses and stops in right time..

I'm glad problem is solved, but does anyone have any idea about this stuation?

Here is working codes I compiled last.


DEFINE OSC 16

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 TMR0_INT, _kesme, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

; enable Timer 0 interrupts

ADCON1=7
'Defining Port usages and clearing ports for start
TRISA=%00000000
TRISB=%00000000
TRISC=%11110000
TRISD=%00000011
PORTA=0
PORTB=0
PORTC=0
PORTD=0

'DEFINE ENCODER INPUTS
SYMBOL EN1=PORTC.7
SYMBOL EN2=PORTC.6
SYMBOL EN3=PORTC.5
SYMBOL EN4=PORTC.4
SYMBOL EN5=PORTD.1
SYMBOL EN6=PORTD.0
'DEFINE MOTOR CONTROL OUTPUTS
SYMBOL M1A=PORTB.7
SYMBOL M1B=PORTB.6
SYMBOL M2A=PORTB.5
SYMBOL M2B=PORTB.4
SYMBOL M3A=PORTB.3
SYMBOL M3B=PORTB.2
SYMBOL M4A=PORTD.7
SYMBOL M4B=PORTD.6
SYMBOL M5A=PORTD.5
SYMBOL M5B=PORTD.4
SYMBOL M6A=PORTD.3
SYMBOL M6B=PORTD.2
'DEFINE VARIABLES
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
EN1PRE var BIT
EN1NOW var BIT
EN2PRE var BIT
EN2NOW var BIT
EN3PRE var BIT
EN3NOW var BIT
EN4PRE var BIT
EN4NOW var BIT
EN5PRE var BIT
EN5NOW var BIT
EN6PRE var BIT
EN6NOW var BIT
M1STEPSIZE VAR BYTE
M2STEPSIZE VAR BYTE
M3STEPSIZE VAR BYTE
M4STEPSIZE VAR BYTE
M5STEPSIZE VAR BYTE
M6STEPSIZE VAR BYTE
M1STATE VAR BYTE
M2STATE VAR BYTE
M3STATE VAR BYTE
M4STATE VAR BYTE
M5STATE VAR BYTE
M6STATE VAR BYTE
STANDC VAR BYTE
M1C var BIT
M2C var BIT
M3C var BIT
M4C var BIT
M5C var BIT
M6C var BIT
walk_mode var byte
duty_check var BIT
duty_ctrl var BIT
duty1 var byte
duty0 var byte
M1POWER var BIT
M2POWER var BIT
M3POWER var BIT
M4POWER var BIT
M5POWER var BIT
M6POWER var BIT
STANDUP_COUNT VAR BYTE
CLEAR 'Clear all variables
'Defining starting values of some variables
M1STEPSIZE=50
M2STEPSIZE=50
M3STEPSIZE=50
M4STEPSIZE=50
M5STEPSIZE=50
M6STEPSIZE=50
EN1PRE=EN1
EN2PRE=EN2
EN3PRE=EN3
EN4PRE=EN4
EN5PRE=EN5
EN6PRE=EN6
M1POWER=0
M2POWER=0
M3POWER=0
M4POWER=0
M5POWER=0
M6POWER=0
STANDUP_COUNT=50

pause 2000
walk_mode=0 'walk_mode defines which movement mode RHEX will use
OPTION_REG=%10000100
TMR0=255 'Start Timer so interrupts and movement will start

@ INT_ENABLE TMR0_INT


'RHEX IS STANDING UP
'Check every motor encoder value and stop releated motor if it reached to
'defined position
'MXC is used for motor running control, if a motor is reached to desired
'position and stopped, do not check and lose time on it
STANDUP:
gosub ENCOUNTER
IF M1C=0 THEN
IF M1STATE>=STANDUP_COUNT THEN
M1POWER=1
M1C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M2C=0 THEN
IF M2STATE>=STANDUP_COUNT THEN
M2POWER=1
M2C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M3C=0 THEN
IF M3STATE>=STANDUP_COUNT THEN
M3POWER=1
M3C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M4C=0 THEN
IF M4STATE>=STANDUP_COUNT THEN
M4POWER=1
M4C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M5C=0 THEN
IF M5STATE>=STANDUP_COUNT THEN
M5POWER=1
M5C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M6C=0 THEN
IF M6STATE>=STANDUP_COUNT THEN
M6POWER=1
M6C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF STANDC>=6 THEN
@ INT_DISABLE TMR0_INT
M1STATE=0
M2STATE=0
M3STATE=0
M4STATE=0
M5STATE=0
M6STATE=0
STANDC=0
PAUSE 2000
end
ELSE
GOTO STANDUP
ENDIF
end

'COUNTING PULSES FROM ENCODER OUTPUTS
'Read values of encoders and if they are different from previous value
'then it means, a transition is occured, so a pulse is given
'increase the releated encoder count
'Note: This will cause 2 counts for every pulse, not 1 count for 1 pulse.

ENCOUNTER:
EN1NOW=EN1
EN2NOW=EN2
EN3NOW=EN3
EN4NOW=EN4
EN5NOW=EN5
EN6NOW=EN6
IF EN1NOW!=EN1PRE THEN
M1STATE=M1STATE+1
ENDIF
EN1PRE=EN1NOW
IF EN2NOW!=EN2PRE THEN
M2STATE=M2STATE+1
ENDIF
EN2PRE=EN2NOW
IF EN3NOW!=EN3PRE THEN
M3STATE=M3STATE+1
ENDIF
EN3PRE=EN3NOW
IF EN4NOW!=EN4PRE THEN
M4STATE=M4STATE+1
ENDIF
EN4PRE=EN4NOW
IF EN5NOW!=EN5PRE THEN
M5STATE=M5STATE+1
ENDIF
EN5PRE=EN5NOW
IF EN6NOW!=EN6PRE THEN
M6STATE=M6STATE+1
ENDIF
EN6PRE=EN6NOW
return
'TMR0 INTERRUPT ROUTINE
'All motor movements are provided by this interrupt routine
'A PWM signal is created by using TMR0 timer and applied to
'motors, all PWM signals will be created by TMR0 for all movement types
kesme:
if walk_mode=0 then
duty1=90
duty0=(256-duty1)
if duty_check=0 then
duty_ctrl=1
M1A=1
M1B=M1POWER
M2A=M2POWER
M2B=1
M3A=1
M3B=M3POWER
M4A=M4POWER
M4B=1
M5A=1
M5B=M5POWER
M6A=M6POWER
M6B=1
TMR0=duty1
endif
if duty_check=1 then
duty_ctrl=0
M1A=0
M1B=0
M2A=0
M2B=0
M3A=0
M3B=0
M4A=0
M4B=0
M5A=0
M5B=0
M6A=0
M6B=0
TMR0=duty0
endif
endif
if duty_ctrl=1 then
duty_check=1
else
duty_check=0
endif
@ INT_RETURN
end

Demon
- 22nd April 2013, 20:35
You did more than just comment/uncomment.

You no longer Goto RST at the bottom of Standup and did some finetuning of code.

I'm happy you nowhave it working. DT-INT really does make our life easier.

Robert