PDA

View Full Version : Pulsin within subroutine



Wesley
- 9th January 2009, 23:11
How do you get PBP to actively read the Pulsin variable within a subroutine? This code needs to constantly check the Pulsin variable in order to actively change the motors speed when the toggle on the remote is moved, and I can't get it to work. What am I doing wrong? Help!

DEFINE OSC 20
OSCCON.4 = 1
OSCCON.5 = 1
OSCCON.6 = 1

'Define I/O pin names
motor_dir VAR PORTB.5 'Motor H-Bridge direction line
motor_pwm VAR PORTB.6 'Motor H-bridge pulse-width-Mod
stop_button VAR PORTB.0 'Stop button on PORTB.0
brake1 VAR PORTB.2 'Brake on pin B.2

'Declare Variables
motor_speed VAR BYTE 'Motor speed as percentage of maximum
motion_dir VAR BIT 'Motor direction
on_time VAR WORD 'PWM ON pulse width
off_time VAR WORD 'PWM OFF pulse width
pwm_cycles VAR BYTE '# of PWM pulses sent
widthx VAR BYTE 'Name to store pulse value

'Define Constants
pwm_period CON 50 'Period of each motor PWM signal cycle
CW CON 1 'Rotate the motor clockwise
CCW CON 0 'Rotate the motor counter clockwise
Pulse CON 50

'Initialize I/O and Variables
TRISB.6 = 0 'Configure H-bridge DIR pin as an output
TRISB.5 = 0 'Configure H-bridge PWM pin as an output
TRISB.1 = 1 'Configure input pulse pin as an input
TRISB.2 = 0 'Configure brake pin as an output
motion_dir = CW 'Starting motor direction: CW (forward)
motor_speed = 50 'Starting motor speed = 50% duty cycle
Low motor_pwm 'Make sure the motor is off to begin with

start:
pulsin PORTB.1,1,widthx
IF widthx >= 50 && widthx < 70 Then run_motor1
IF widthx >70 && widthx <90 Then Goto run_motor2
IF widthx >90 Then
Goto run_motor3
Else
Goto brake
Endif
Return

'Subroutine to run motor at the desired speed and direction
run_motor1:
Low Brake1
'Set the motor direction
motor_dir = CW
motor_speed = 50
'Output PWM signal
Gosub pwm_periods 'Calculate the on and off pulse widths
While (widthx >= 50 && widthx < 70)
Gosub pwm_pulse 'Send out a full PWM pulse
Wend
Goto start

Charles Linquis
- 10th January 2009, 01:57
I can't see all your subroutines, but I certainly hope you are using the hardware PWM routines, not the ones built in to PBP!

Wesley
- 10th January 2009, 02:04
Here's the entire code, it it helps...

DEFINE OSC 20
OSCCON.4 = 1
OSCCON.5 = 1
OSCCON.6 = 1

'Define I/O pin names
motor_dir VAR PORTB.5 'Motor H-Bridge direction line
motor_pwm VAR PORTB.6 'Motor H-bridge pulse-width-modulation line
stop_button VAR PORTB.0 'Stop button on PORTB.0
brake1 VAR PORTB.2 'Brake on pin B.2

'Declare Variables
motor_speed VAR BYTE 'Motor speed as percentage of maximum (0 to 100)
motion_dir VAR BIT 'Motor direction (1:CW/Forward 0:CCW/Reverse)
on_time VAR WORD 'PWM ON pulse width
off_time VAR WORD 'PWM OFF pulse width
pwm_cycles VAR BYTE '# of PWM pulses sent during the position control loop
widthx VAR BYTE 'Name to store pulse value
run1 VAR BYTE

'Define Constants
pwm_period CON 50 'Period of each motor PWM signal cycle (in microsec)
CW CON 1 'Rotate the motor clockwise
CCW CON 0 'Rotate the motor counter clockwise
Pulse CON 50

'Initialize I/O and Variables
TRISB.6 = 0 'Configure H-bridge DIR pin as an output
TRISB.5 = 0 'Configure H-bridge PWM pin as an output
TRISB.1 = 1 'Configure input pulse pin as an input
TRISB.2 = 0 'Configure brake pin as an output
motion_dir = CW 'Starting motor direction: CW (forward)
motor_speed = 50 'Starting motor speed = 50% duty cycle
Low motor_pwm 'Make sure the motor is off to begin with

start:
pulsin PORTB.1,1,widthx
IF widthx >= 50 && widthx < 70 Then run_motor1
IF widthx >70 && widthx <90 Then Goto run_motor2
IF widthx >90 Then
Goto run_motor3
Else
Goto brake
Endif
Return

'Subroutine to run motor at the desired speed and direction
run_motor1:
Low Brake1
'Set the motor direction
motor_dir = CW
motor_speed = 50
'Output PWM signal
Gosub pwm_periods 'Calculate the on and off pulse widths
While (widthx >= 50 && widthx < 70)
Gosub pwm_pulse 'Send out a full PWM pulse
Wend
Goto start

run_motor2:
Low Brake1
'Set the motor direction
motor_dir = CCW
motor_speed = 70
'Output PWM signal
Gosub pwm_periods 'Calculate the on and off pulse widths
While (stop_button == 0) 'Until the stop button is pressed
Gosub pwm_pulse 'Send out a full PWM pulse
Wend
Goto start

run_motor3:
Low Brake1
'Set the motor direction
motor_dir = CW
motor_speed = 100
'Output PWM signal
Gosub pwm_periods 'Calculate the on and off pulse widths
While (stop_button == 0) 'Until stop button is pressed
Gosub pwm_pulse 'Send out a full PWM pulse
Wend
Goto start

'Subroutine to calculate the PWM on and off pulse widths based on the desired
'motor speed
pwm_periods:
'Be careful to avoid integer arithmetic
IF (pwm_period >= 655) Then
on_time = pwm_period/100 * motor_speed
off_time = pwm_period/100 * (100 - motor_speed)/100
Else
on_time = pwm_period*motor_speed/100
off_time = pwm_period*(100 - motor_speed)/100
Endif
Return

'Subroutine to output a full PWM pulse based on the data from pwm_periods
pwm_pulse:
'Send the ON pulse
High motor_pwm
Pauseus on_time

'Send the OFF pulse
Low motor_pwm
Pauseus off_time
Return

brake:
'brake motor
High brake1
Goto start

Charles Linquis
- 10th January 2009, 03:15
Is this supposed to run the motor continuously? Again - why aren't you using the hardware PWM facilities provided by most PICs?

Wesley
- 10th January 2009, 03:37
The program is supposed to run the motor until the remote control lever isn't pushed the right distance, creating a different pulse width. The PWM is just fine, that isn't the problem. So far, when the lever is pushed over to the area of speed two or three, it will run the motor until the stop button is pushed. I need it to run the motor until the lever is no longer creating the right pulse. This is why I've attempted to change run_motor1. Since this program needs to be controlled by remote control only, I nee the run_motor1 subroutine to recognize the widthx value, and return to main when the lever is in a different position. I haven't had luck with the hardware PWM or HPWM command. Calculating the pulse on and off time is more reliable. I just can't make it recognize the pulse when in the subroutine, in order to return to the main program.

Charles Linquis
- 10th January 2009, 04:47
I don't see why you have a RETURN at the position shown below. I can imagine that the RETURN is popping a strange address off the stack.


start:
pulsin PORTB.1,1,widthx
IF widthx >= 50 && widthx < 70 Then run_motor1
IF widthx >70 && widthx <90 Then Goto run_motor2
IF widthx >90 Then
Goto run_motor3
Else
Goto brake
Endif
Return <--- why this?

LinkMTech
- 10th January 2009, 04:54
Although I didn't try to completely understand the routine, I did notice something off...
You have RETURN at the end of the start loop but don't see where it was GOSUB'd from. Is it suppose to be GOTO?


start:
pulsin PORTB.1,1,widthx
IF widthx >= 50 && widthx < 70 Then run_motor1
IF widthx >70 && widthx <90 Then Goto run_motor2
IF widthx >90 Then
Goto run_motor3
Else
Goto brake
Endif
Return

Just a thought and not sure if it would even make a difference.

Wesley
- 10th January 2009, 22:16
I removed the return command, but I still can't get it to read the pulsin variable within the subroutine. It it impossible? What should I do?

start:
pulsin PORTB.1,1,widthx
IF widthx >= 50 && widthx < 70 Then run_motor1
IF widthx >70 && widthx <90 Then Goto run_motor2
IF widthx >90 Then
Goto run_motor3
Else
Goto brake
Endif

run_motor1:
Low Brake1
motor_dir = CW
motor_speed = 50
Gosub pwm_periods
While (widthx >= 50 && widthx < 70)
Gosub pwm_pulse
Wend
Goto start

Wesley
- 10th January 2009, 23:05
Charles you were right. I've always had issues with the PWM command, but following your comment I re-wrote the program using PWM, and now I have no problem. Thanks!