Picaxe PWM

Post Code you'd like to share here!

Picaxe PWM

Postby slurp on Sun Jun 15, 2014 9:26 pm

I've been a little slow to post this was shared by David Hannaford when we met at one of the recent Midland Robot Club meets.

A Picaxe CHI035 projet board was used with the following modifications:

circuit mod.jpg
Modified Circuit
circuit mod.jpg (178.44 KiB) Viewed 779 times


Code: Select all
'PICAXE PROGRAMME for laser cut Mini Sumo chassis at KES
'Version using PWM on pins 3 & 6 for speed control
'These 2 pins are the only ones that can be used for PWM on 18M2
'Tech Supplies CHIO35 board with PicAxe18M2 and L293D motor driver
' hacked to use pin b3 instead of b4 to drive L293D so 2 pwms can be used
' 18M2 pin 10 bent out so it does not make contact in socket
' pins b3 and b4 connected together on port b contacts in centre
'Rapid RF500TB 14415 6V motors
'Farnell 12 tooth 0.5 mod pinion and laser cut 80 tooth main gear
'Laser cut perspex 50mm wheels
'2 microswitches for detecting contact at front

'Following items not yet implemented:-
'    4 pairs of LEDs & phototansistor sensors

'
'Version 1 David Hannaford
'Oct 2013
'472 bytes used out of 2048 available
'
'PORT ASSIGNMENTS and pins on Picaxe 18M2
'b.0 = Out 0 User Green LED   pin 6  SRI OUT/IN
'b.1 = Out 1         pin 7  I2c sda/Touch/ADC/Out/In
'b.2 = Out 2SF5 if used      pin 8  hserin/Touch/ADC/Out/In
'b.3 = L293D PWM signal      pin 9  PWM/Touch/ADC/Out/In
'b.4 = Not available - hacked   pin 10 I2c scl/Touch/ADC/Out/In
'b.5 = L293D signal      pin 11 hserout/Touch/ADC/Out/In
'b.6 = L293D PWM signal      pin 12 PWM/Touch/ADC/Out/In
'b.7 = L293D signal      pin 13 Touch/ADC/Out/In
'
'c.0 = Front L photo trans   pin 17 Touch/ADC/Out/In
'c.1 = Front R photo trans   pin 18 Touch/ADC/Out/In
'c.2 = Input 2 SF5      pin 1  DAC/Touch/ADC/Out/In
'c.3 = Programmer       pin 2  (SRQ/Out) Serial Out
'c.4 = Programmer       pin 3  (In) Serial In
'c.5 = Reset button      pin 4  In
'c.6 = In 6 left microswitch   pin 15 kb clock/In/Out
'c.7 = In 7   right microswitch pin 16 kb data/In/Out
'
'ground            pin 5
'+2 to +5.5v         pin 14
'
'DIRECTIVES
#picaxe 18M2    'code optimised for Picaxe 18M2
'Add quote mark in front of next line to allow EEPROM overwrite
#no_data        'do not overwrite EEPROM
'
'DECLARE SYMBOLS for CONSTANTS
'assign names to inputs and outputs
symbol Rmotor1 = b.3   'PWM enabled pin
symbol Dontuse = b.4
symbol Rmotor2 = b.5
symbol Lmotor1 = b.6   'PWM enabled pin
symbol Lmotor2 = b.7
symbol LEDno1  = b.0
symbol Rphoto  = c.0
symbol Lphoto  = c.1
symbol RightMsw = pinc.6
symbol LeftMsw = pinc.7   

' assign names for other constants
symbol testdelay = 5000

'
'DECLARE SYMBOLS for VARIABLES bit 0-32, b0-27, w0-13 (overlap each other)
' allowed for 16 bit variables - bit0 to bit 15
symbol LMotorDir = bit0   ' 0 = go forward, 1 = go backwards
symbol RMotorDir = bit1   ' 0 = go forward, 1 = go backwards


' allowed  for 5 word variables w1 to w5
symbol MotorSpeed = w1  ' (b3,b2) working field to calculate inverse value


' allowed for 16 one byte variables from b12 to b27
symbol LmotorSpeed = b12   ' range values 0 stop to 255 fastest
symbol RmotorSpeed = b13   ' range values 0 stop to 255 fastest
symbol programno = b14
symbol LFVal = b15      ' value of left front phototransistor reading
symbol RFVal = b16      ' value of right front phototransistor reading

'
'************************************************************************
'                        INITIALISATION
'************************************************************************
init:
setfreq M32                'operate at32MHz
'
'Configure port B all outputs
let dirsB = %11111111     '1=output, 0=input
'Configure port C all inputs
let dirsC = %00000000     '1=output, 0=input
'

programno = 3   'select default program to run

'************************************************************************
'                        Main program loop
'************************************************************************

high LEDno1      ' switch on LED
pause 2000      ' wait 2 seconds
low LEDno1      ' switch off LED
pause 2000      ' wait 2 seconds
high LEDno1      ' switch on LED

'Select program to run based on programno value
start:
gosub init_pwm   ' set up PWM and motors stopped

testsws:
if programno = 3 then gosub test_pt 'test phototransistor inputs

if LeftMsw = 1 then gosub move_sequence 'do a sequence of moves
if RightMsw = 1 then gosub test_pwm 'do test spin using speed control

goto testsws


if programno = 0 then gosub move_sequence 'do a sequence of moves

if programno = 1 then gosub test_pwm 'do test move using speed control

if programno = 2 then gosub test_msw 'test microswitches

goto start

test_msw:
low LEDno1
if LeftMsw = 1 then high LEDno1
endif
if RightMsw = 1 then high LEDno1
endif
pause 1000

goto test_msw
return

test_pt:
readadc Lphoto,LFVal   ' read left front value into LFVal
readadc Rphoto,RFVal   ' read right front value into RFVal

if RFVal > 192 then high LEDno1 ' high numbers = white
endif
if RFVal <= 192 then low LEDno1 ' low numbers = black
endif



return


test_pwm:

let LMotorDir = 1    ' 0 = go forward, 1 = reverse
let RMotorDir = 0    ' 0 = go forward, 1 = reverse
let LmotorSpeed = 48   ' range 0 to 255
let RmotorSpeed = 48   ' range 0 to 255

pwmloop:
pause 5000
high LEDno1      ' switch on LED
pause 5000
low LEDno1      ' switch off LED

LmotorSpeed = LmotorSpeed + 16
RmotorSpeed = RmotorSpeed + 16
gosub ChangeSpeed


goto pwmloop




' put all the called routines from here on

'************************************************************************
'      initialise the pwm routine
'************************************************************************
' routine to initialise the pwm - call just once at start of program
init_pwm:
low  Lmotor1     'pwm value high = forward
low  Lmotor2   'low = forward left motor

low  Rmotor1     'pwm value high = forward (inverted speed)
high Rmotor2   'high = forward right motor
' period 100 = period time of 12.5 micro seconds - 80 kHz
' period 150 = period time of 19 micro seconds - 52.63 kHz
' period 200 = period time of 25 micro seconds - 40 kHz
' period 255 = period time of 32 micro seconds - 31.25 kHz

' pwmduty 50 = duty time of 1.7 micro seconds
' pwmduty 250 = duty time of 7.8 micro seconds
' pwmduty 500 = duty time of 15 micro seconds
' pwmduty 750 = duty time of 23.5 micro seconds
' pwmduty 1000 = duty time of 31.25 micro seconds
' LmotorSpeed & RmotorSpeed multiplied by 4  before setting pwmduty
'    so that a one byte field can be used for the speed
pwmout Lmotor1,255,0 ' set period to 255, range 0 to 255, speed to 0
pwmout Rmotor1,255,1023 ' set period to 255, range 0 to 255, speed to 0

return

'************************************************************************
'      Change Speed or direction routine
'************************************************************************
' routine called when we want to change the speed after setting new values
' of speed or direction
ChangeSpeed:
if LMotorDir = 0 then gosub LeftForward
if RMotorDir = 0 then gosub RightForward
if LMotorDir = 1 then gosub LeftReverse
if RMotorDir = 1 then gosub RightReverse

return

LeftForward:   ' set motors for forward pwm value on left wheel
low  Lmotor1     'pwm value high = forward
low  Lmotor2   'low = forward left motor
MotorSpeed = LmotorSpeed * 4
pwmduty Lmotor1,MotorSpeed
return

RightForward:   ' set motors for forward pwm value on right wheel
low  Rmotor1     'pwm value high = forward (inverted speed)
high Rmotor2   'high = forward right motor
MotorSpeed = RmotorSpeed * 4
MotorSpeed = 1023 - MotorSpeed ' invert the speed value
pwmduty Rmotor1,MotorSpeed
return

LeftReverse:   ' set motors for forwrad pwm value on left wheel
low  Lmotor1     'pwm value high = forward
high  Lmotor2   'high = reverse left motor
MotorSpeed = LmotorSpeed * 4
MotorSpeed = 1023 - MotorSpeed ' invert the speed value
pwmduty Lmotor1,MotorSpeed
return

RightReverse:   ' set motors for forwrad pwm value on right wheel
low  Rmotor1     'pwm value high = forward (inverted speed)
low Rmotor2      'low = reverse right motor
MotorSpeed = RmotorSpeed * 4
pwmduty Rmotor1,MotorSpeed
return




'************************************************************************
'      move sequence routine
'************************************************************************

move_sequence:

seqstart:
pause testdelay


gosub motorfwd      ' go forward with both motors
pause testdelay

gosub motorstop      ' stop both motors
pause testdelay

gosub motorrev      ' reverse both motors
pause testdelay

gosub motorstop      ' stop both motors
pause testdelay

gosub turnleft      ' turn left
pause testdelay

gosub motorstop      ' stop both motors
pause testdelay

gosub turnright      ; turn right
pause testdelay

gosub motorstop      ' stop both motors
pause testdelay

gosub spinleft      ' spin left (anticlockwise)
pause testdelay

gosub motorstop      ' stop both motors
pause testdelay

gosub spinright      ' spin right (clockwise)
pause testdelay

gosub motorstop      ' stop both motors
pause testdelay

pause testdelay
pause testdelay
pause testdelay

goto seqstart

return

'
'************************************************************************
'      steering direction routines
'************************************************************************


motorfwd:      ' both motors forward
high Lmotor1   '1 high, 2 low = left motor forward
low  Lmotor2   '
low  Rmotor1     '1 low, 2 high = right motor forward
high Rmotor2   '
return

motorstop:      ' both motors stopped
high Lmotor1   '1 high, 2 high = left motor stop
high Lmotor2   '
high Rmotor1     '1 high, 2 high = right motor stop
high Rmotor2   '
return

motorrev:      ' both motors reversed
low  Lmotor1   '1 high, 2 low = right motor reverse
high Lmotor2
high Rmotor1     '1 low, 2 high = left motor forward
low  Rmotor2   '
return

turnright:      ' turn right by stopping right wheel
high Lmotor1   '1 high, 2 low = left motor forward
low  Lmotor2   '
high Rmotor1     '1 high, 2 high = right motor stop
high Rmotor2   '
return

turnleft:      ' turn left by stopping left wheel
high Lmotor1   '1 high, 2 high = left motor stop
high Lmotor2   '
low  Rmotor1     '1 low, 2 high = right motor forward
high Rmotor2   '
return

spinleft:      ' spin anti-clockwise
low  Lmotor1   '1 low, 2 high = left motor reverse
high Lmotor2   '
low  Rmotor1     '1 low, 2 high = right motor forward
high Rmotor2   '
return

spinright:      ' spin clockwise
high Lmotor1   '1 high, 2 low = left motor forward
low  Lmotor2   '
high Rmotor1     '1 high, 2 low = right motor reverse
low  Rmotor2   '
return
slurp
Site Admin
 
Posts: 1027
Joined: Thu Dec 29, 2005 8:15 pm
Location: Milton Keynes, UK

Return to Source Code

Who is online

Users browsing this forum: No registered users and 1 guest

cron